国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

說說Prototypal Inheritance

jzzlee / 778人閱讀

摘要:因為是一種長程的關(guān)聯(lián),基類的修改對繼承者的影響難以估計和維護,具有特性,因此從耦合度的角度說,它大大提高了組件的耦合度,高耦合度不是罪過,但它應(yīng)對變化的能力變差了。

JavaScript開發(fā)者的繁殖速度和它的語言特性一樣迅猛,這是好事,但是也把JS搞得比任何一種其他語言都更像流行樂,充滿教派和玄學(xué)。但編程不是玄學(xué),是科學(xué)和工程。這篇文章就用來闡述和探討JavaScript中的一個比較關(guān)鍵的概念,雖然在實踐上并不如在理論上那么意義重大。

Prototype Inheritance是JavaScript里的一個標(biāo)志性特性。實際上它叫做Inheritance是有一些問題的,JS沒有type系統(tǒng),instanceof也只是一個沿著原型鏈查找constructor的語法糖,一個對象是誰構(gòu)造出來的并不說明任何問題,因為它的對象沒有結(jié)構(gòu)上的穩(wěn)定性承諾,只能靠程序員自覺。

Inheritance是OO近30年的工程實踐里留下來的重要特性,但是它不是一個好的特性。當(dāng)然好與不好是相對的,在絕大多數(shù)情況下它都不是太大的問題,尤其是工程進入尾聲,開發(fā)者對問題和模型有充分認識的時候,Class Hierarchy可以是很合理的設(shè)計。

那么,在更General的層面上去問Inheritance設(shè)計解決的是什么問題呢?兩個字,reuse。

在Java里,reuse有兩個語法關(guān)鍵字,一個是extends,即inheritance,另一個是implements,實現(xiàn)interface。

那么為什么把implements也當(dāng)成reuse呢?因為任何模塊總有兩個方面,使用者和提供者,implements實現(xiàn)了一個interface,所以等價于重用了使用者代碼。

當(dāng)然你說extends也達到了同樣的目的呀?而且我還重用了父類的狀態(tài)和行為呢?是的,凡是兩面,有得有失;這正是它倒霉的地方。

它倒霉的具體情況被稱為fragile base class問題,wiki上有詞條,不贅述。

因為extends/inheritance是一種長程的關(guān)聯(lián),基類的修改對繼承者的影響難以估計和維護,具有ripple effect特性,因此從耦合度的角度說,它大大提高了組件的耦合度,高耦合度不是罪過,但它應(yīng)對變化的能力變差了。

好了,說了這么多我們說到了問題的本原。

在Self語言中,也是最早試圖解決這個問題的語言設(shè)計者們,給出了Prototypal Inheritance設(shè)計,

它的設(shè)計初衷有兩個:

抹平Class和Object的差異,讓修改基類變得容易;

如果你修改基類,復(fù)制一個基類對象然后修改,新繼承者從新的基類對象開始繼承。其他繼承者不受影響。

你覺得這個差別很重要嗎?其實在實踐上沒有想象的那么重要。

JavaScript在設(shè)計上還有點不同,它的原型對象是共享而非復(fù)制的,結(jié)果是只適合把方法裝載到原型上去,偶爾有一些同類對象相同的只讀context也可以這樣做,其他每對象私有態(tài)還得通過調(diào)用父類構(gòu)造函數(shù)做出來,即ES6里的super關(guān)鍵字,如果是ES5,得手動把this bind到父類構(gòu)造函數(shù)上調(diào)用。這個特性就語言而言是重要特性,但是和我們討論的問題沒太大關(guān)系。

更重要的問題出在設(shè)計上而不是語言層面。

James Gosling在一次研討會上回答問題時,有人問了他這樣一個問題,如果重新設(shè)計Java語言,他會有什么重要的取舍。Gosling的回答可能有點兒令你吃驚:他說如果可以重新來過,他不會賦予Java語言繼承特性,只用implements。

呃?!

其實是可以理解的。

繼承設(shè)計看起來在代碼重用上很方便,但是它的fragile base class問題,讓它無法應(yīng)對軟件系統(tǒng)的scale問題。這一點不用論證,在整個軟件工業(yè)上,繼承這種whitebox reuse不能scale是一個定論,單一程序用繼承書寫代碼不是問題,但是任何有點規(guī)模的系統(tǒng)都是靠interface,protocol,或者所謂的component-based工程方法來搭建的,也就是在更高粒度的設(shè)計層面只有基于Interface的blackbox reuse。

在任何語言中,都能用blackbox reuse構(gòu)建復(fù)雜系統(tǒng)。在JavaScript中,龐大的npm包系統(tǒng)實現(xiàn)的最終應(yīng)用,也是blackbox reuse。

JavaScript本身是否functional是洗剪吹們喜歡探討的,嚴(yán)肅的工程師不該干這個事兒;但是整個JavaScript的Community的共識是基于blackbox reuse構(gòu)建系統(tǒng),這是好事。

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

那么是否該使用extends呢?

很多時候沒什么必要性。既然Gosling都說不該去通過inheritance-based hierarchy去組合復(fù)雜行為(犧牲低耦合度),誰還比他更有資格對這個問題發(fā)言呢?

通常可以把幾個邏輯單元糖葫蘆一樣串起來實現(xiàn)一個從外部看來功能特別Powerful的一個對象時,也很容易把每個獨立單元用decorator,facade之類的pattern串起來,可能會多寫點兒代碼,但不會很多,JavaScript作為無類型動態(tài)語言在書寫pattern時具有顯著的簡潔優(yōu)勢。(在C++/Java里是相反的,只寫inheritance顯著比寫pattern簡潔;但是問題就是問題你無法回避,如果必須要松開耦合,還得回到pattern上定義,這也是為什么這些pattern被發(fā)明出來的原因。)

當(dāng)然用extends方便的時候也沒必要去抵觸它,比如node里的event emitter,stream等等,該用就用唄,只要不去試圖構(gòu)造framework一樣的hierarchy即可。

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

如果有人跟你說JavaScript不是OO語言,請一腳把它踹溝里去,JS里除了用Object Literal寫出來的ex nihilo對象之外,(邏輯上)所有對象都是用構(gòu)造函數(shù)構(gòu)造出來的,這甚至包括全局的Object, Array,F(xiàn)unction等等,一切皆對象是JS的最高設(shè)計思想。你怎么能說它不是OO的?

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://specialneedsforspecialkids.com/yun/86529.html

相關(guān)文章

  • 理解JavaScript的核心知識點:原型

    摘要:首先,需要來理清一些基礎(chǔ)的計算機編程概念編程哲學(xué)與設(shè)計模式計算機編程理念源自于對現(xiàn)實抽象的哲學(xué)思考,面向?qū)ο缶幊淌瞧湟环N思維方式,與它并駕齊驅(qū)的是另外兩種思路過程式和函數(shù)式編程。 JavaScript 中的原型機制一直以來都被眾多開發(fā)者(包括本人)低估甚至忽視了,這是因為絕大多數(shù)人沒有想要深刻理解這個機制的內(nèi)涵,以及越來越多的開發(fā)者缺乏計算機編程相關(guān)的基礎(chǔ)知識。對于這樣的開發(fā)者來說 J...

    iKcamp 評論0 收藏0
  • 每個 JavaScript 工程師都應(yīng)當(dāng)知道的 10 個面試題

    摘要:所支持的面向?qū)ο缶幊贪ㄔ屠^承。發(fā)明于年的就是首批支持函數(shù)式編程的語言之一,而演算則可以說是孕育了這門語言。即使在今天,這個家族的編程語言應(yīng)用范圍依然很廣。 1. 能說出來兩種對于 JavaScript 工程師很重要的編程范式么? JavaScript 是一門多范式(multi-paradigm)的編程語言,它既支持命令式(imperative)/面向過程(procedural)編程...

    jone5679 評論0 收藏0
  • 每個 JavaScript 工程師都應(yīng)當(dāng)知道的 10 個面試題

    摘要:所支持的面向?qū)ο缶幊贪ㄔ屠^承。發(fā)明于年的就是首批支持函數(shù)式編程的語言之一,而演算則可以說是孕育了這門語言。即使在今天,這個家族的編程語言應(yīng)用范圍依然很廣。 1. 能說出來兩種對于 JavaScript 工程師很重要的編程范式么? JavaScript 是一門多范式(multi-paradigm)的編程語言,它既支持命令式(imperative)/面向過程(procedural)編程...

    YorkChen 評論0 收藏0
  • 每個 JavaScript 工程師都應(yīng)當(dāng)知道的 10 個面試題

    摘要:所支持的面向?qū)ο缶幊贪ㄔ屠^承。發(fā)明于年的就是首批支持函數(shù)式編程的語言之一,而演算則可以說是孕育了這門語言。即使在今天,這個家族的編程語言應(yīng)用范圍依然很廣。 1. 能說出來兩種對于 JavaScript 工程師很重要的編程范式么? JavaScript 是一門多范式(multi-paradigm)的編程語言,它既支持命令式(imperative)/面向過程(procedural)編程...

    Gilbertat 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<