2010-01-19 43 views
13

有很多文章和文章解釋JavaScript繼承如何工作,但爲什麼JavaScript使用原型繼承而不是經典繼承來實現?爲什麼使用原型繼承實現JavaScript?

我喜歡JavaScript,所以我不是說這是壞事......我只是好奇。

+7

標記爲社區維基請.. – 2010-01-19 02:16:55

+0

JavaScript的創建者是一個Stackoverflow用戶嗎? – 2010-01-19 02:23:04

+1

@Gaby - 在那裏有一個答案。 – ChaosPandion 2010-01-19 02:24:22

回答

1

我認爲這是因爲它很容易實現,不需要額外的關鍵字,用戶不需要了解它就可以使用該語言。它比基於類的繼承更強大和靈活。

這是非類型語言的自然選擇。基於類的繼承的主要優點是它允許靜態類型,因此允許類型檢查和更快的基於表的查找實現。

+0

我想知道「易於實施」的說法。雖然這在對象繼承方面可能是正確的,但如果您認爲JavaScript的一流功能非常強大,並且我相信根本不可能實現(部分應用程序,閉包,等等。)。 – stakx 2010-01-22 20:41:56

12

除非JavaScript中的一位設計師停下來衡量,否則我們只能推測。這已經說了,這是我的看法:

JavaScript是按照它的解釋執行的,所以沒有將對象類型的聲明與對象本身分離的概念。這是一個非常實用的方法。這個實例在描述時就已經存在 - 我們總是在活動實例上運行。正因爲如此,類的概念 - 或被動的「實例模板」 - 沒有真正的地方。

+4

有很多使用類的腳本語言。 – 2011-06-28 18:09:10

+0

這與說原型是一樣的,因爲它是原型的。並不是說你在說,但結論是無意義的。 – 2011-11-09 06:20:05

+0

@SeanMcMillan真的,我不打算暗示語言*必須*以這種方式工作,因爲它是一種腳本語言,而非相當方便。 – 2011-11-10 01:21:26

8

JavaScript原本應該和Lisp非常相似。即使語法更改爲更接近C/Java之後,它仍然是Lisp in C's clothing。我認爲答案在於它是函數式編程的起源。在純FP中,沒有可變狀態,這意味着沒有可變對象。如果你稍微放鬆一些規則並稍微有點創意,最終會得到類似繼承的東西,即可以擴展對象但不能修改原始對象。它提供了與繼承一樣的力量,並且仍然給你一些不變性。

最後,扭轉語言使其看起來像C++和Java,中提琴,你有new someFunction(),其餘的是歷史。

+1

你的意思是「沒有可變狀態,這意味着沒有可變對象」? – 2010-01-19 02:38:03

+0

@Andre:在** pure **函數式編程(例如Erlang)中,所有變量都是常量。在變量被實例化後,它們所保存的值不能被修改。由於我們使用變量引用對象,這意味着純FP中的對象不能被修改:所有對象都是常量。 – slebetman 2010-01-19 02:45:30

+0

好吧,但在JavaScript中,如果我這樣做:var a = {name =「n」,age = 1}。 a.age = 2.我在做什麼?重新實例化'a'? – 2010-01-19 02:49:57

1

原型繼承(封閉)允許別人做從未想過的事情。這是幾個範例的網格化,它們彙集在一起​​以實現通用目的的編程。

使用原型語言,您可以爲您的課程「混合」。您可以完成您希望的封裝級別,而無需使用特定於語言的關鍵字。簡而言之,原型語言非常棒。

我討厭這麼說,但是JavaScript和一些庫可以滿足我需要的一切。它的發展是顛覆性的(應該是從屬於Java的)。它在最簡單的實現中具有很大的能力。

隨着足夠的學習/玩耍,你會開始看到它的靈感的優點。 JavaScript是少數幾個有意識地隱藏它的語言之一。如果你想知道「爲什麼」,你必須深入政治。但是,正是出於這個原因,這太棒了。

+0

@Pestilence,你能指點我一些資源來「做從未想過的事情」嗎? 例如,通過混入,我可以通過設置原型來從對象中獲取方法,但是我只能這樣做一次,對嗎?除非我做某些事情,而不需要原型如下: - 我有一個對象X,我想它擁有Y.doSomething - X.doSomething = Y.doSomething - (只是設置了Y.doSomething的引用,如果我希望它獨立地擁有它) – ambertch 2010-01-21 20:57:23

+0

那麼,模擬類繼承是你可以做的一件事......但是,你真的不需要擔心動態類型語言中的層次結構。只需將一個或多個原型克隆到新實例中即可。 您可以做的事情包括:通過混合來自其他「類」的方法和初始化工具來動態構建「類」和實例。在「施工」中以編程方式更改界面。即使改變基地「班」。修改所有字符串對象以包含Base64方法是我喜歡做的事情:「foo」.base64()。 – pestilence669 2010-01-22 20:18:47

+0

對於自定義類,您所指的原型屬性可以被認爲是可選的。你可以控制並完全繞過它。 – pestilence669 2010-01-22 20:25:59

5

因爲它深受Self的影響。維基百科和ECMA-spec都提到了這一點。

15

這裏是布蘭登·艾克不得不說發生了什麼: http://weblogs.mozillazine.org/roadmap/archives/2008/04/popularity.html

正如我經常說,和其他在網景可以確認,我應聘到網景以「做計劃的承諾「在瀏覽器中。至少客戶端工程管理包括Tom Paquin,Michael Toy和Rick Schell以及一些名爲Marc Andreessen的人確信Netscape應該以源代碼的形式在HTML中嵌入一種編程語言。

來自高級工程管理的diktat語言必須「看起來像Java」。這排除了Perl,Python和Tcl以及Scheme。

我並不自豪,但我很高興我選擇了Scheme-ish一流的功能和Self-ish(儘管單一)原型作爲主要成分。 Java的影響,特別是y2k日期錯誤,但也包括原始與對象的區別(例如,字符串與字符串),是不幸的。