2012-10-02 32 views
2

原因是,雖然我們可以在Javascript中使用僞古典繼承,但實際上我們必須實現我們自己的extendinherit在ECMA-262或ECMA 5.1之前,Javascript是否沒有僞古典繼承或原型繼承支持?

怎麼樣的原型繼承 - 我認爲它確實有此功能,如果使用foo.bar,如果bar不是foo屬性,解釋或編譯的代碼(例如,如果使用谷歌V8)將上升原型鏈,但沒有內置的方法使對象b的隱藏原型屬性指向a作爲原型鏈。我們必須通過定義clone()函數或Object.create()來添加它。更重要的是,我認爲我在純原型繼承代碼中看到沒有任何構造函數。所以它看起來像在原型代碼中,沒有構造函數(構造函數)。但是如果我們使用原型繼承,我們實際上必須使用構造函數來實現clone()--這更像是僞經典繼承方面。

因此,似乎原來的Javascript實際上既不是僞古典也不是Prototypal繼承?根據this Wikipedia article的說法,我認爲它需要在10天內上市,否則會有更糟的情況出現在市場上。但是我也想知道爲什麼1995年Javascript出現後的1年或2年,至少Netscape版本的Javascript沒有添加extendObject.create()方法?

這個問題旨在理解和闡明Javascript的僞古典和原型部分的一些概念。這是真的 - 原來的Javascript本身不具備僞古典或原型繼承支持?

回答

2

最初的目標是猿類語言,使JS看起來足夠熟悉,以加快採用。沒有人以任何方式使用JS幾乎足夠先進,在1997年甚至考慮到看原型的麻煩。

人們仍然喜歡拍對象:

var car = new Object(); 
car.doors = 4; 
car.wheels = 4; 
car.position = new Object(); 
car.position.x = 230; 
car.position.y = 400; 

更妙的是誰使用陣列,使這些對象的人。

var car = new Array(); 
car["doors"] = 4; 
car["wheels"] = 4; 
car["position"] = new Array(); 
car["position"]["x"] = 230; 
car["position"]["y"] = 400; 

這就是一個很多JS看上去就像在那些日子裏。老實說,仍然有很多看起來像這樣的東西,因爲人們仍然來自Java或C#或C++或PERL或PHP,並認爲它看起來很熟悉以至於不需要它們麻煩學習它 - 他們可以將數組轉換爲對象,或集合,或字典,這沒關係......

而這就是他們所做的。

沒有人認爲JS會是一個大問題。沒有人想到這一點。所以瀏覽器間的標準在它已經成爲一件大事之前並沒有出現,並且在那時,每個人都對JS 有不同的想法。

儘管如此,Internet Explorer擁有最廣泛的市場份額,以及最破碎和非標準的JS實施...... 這已經發生了變化,但嚴重的是,我們現在只是觸及一個點,所有新的說事的瀏覽器版本,其被概括和標準化的一半十年前(大5)支持功能...

...這就是它需要多長時間來扭轉一條船,當你在談論類似這個。

+0

+1的歷史解釋...順便說一句,唯一有道理的... – opensas

1

經典的繼承是不是官方語言功能,但原型繼承(和已經很長一段時間),但它是一個有點笨拙。

但事實證明,您可以用原型複製古典繼承,但不能以其他方式複製古典繼承。有很多這樣的庫。我喜歡John Resig的herebackbonecoffee script classes

你確實有構造函數,但沒有超級。

Here's an example of how to do simple inheritance in plain old javascript.

// Parent "class" 
var Foo = function() { 
    this.barVal = 'baz'; 
}; 

// Parent instance method 
Foo.prototype.bar = function() { 
    return this.barVal; 
}; 

// Test out an instance 
var foo = new Foo(); 
console.log(foo.bar()); // 'baz' 






// Child "class" 
var Foo2 = function() { 
    Foo.call(this); // invokes previous constructor 
}; 

// Assign prototypical ancestor 
Foo2.prototype = new Foo(); 

// Child instance method 
Foo2.prototype.bar = function() { 
    var prevResult = Foo.prototype.bar.call(this); // invoke previous method implementation 
    return prevResult + '!'; 
} 

// New child instance method 
Foo2.prototype.newMethod = function() { // new method only on child class 
    return 'Some new method!' 
}; 

// Test out an instance 
var foo2 = new Foo2() 
console.log(foo2.bar()) // 'baz!' 
console.log(foo2.newMethod()) // 'Some new method!'​ 

但這裏也有邊緣的情況。使用一個小型的幫助程序庫來簡化這一過程並不可恥。

+0

是的,這是'Foo2.prototype =新的Foo();'和'Foo2.prototype.constructor = foo2的;'這是'extend'功能的一部分,有的人喜歡用一個空'F( )'因爲那麼'Foo2.prototype'不會有所有這些額外的屬性,並且如果'Foo()'運行起來很複雜,它將不會運行很長時間。 –

+0

有很多方法來構建經典的繼承在JS,有幾分我的觀點。 –