2013-07-13 16 views
1

我正在閱讀kangax的博客How ECMAScript 5 still does not allow to subclass an array。在這裏,他是用子類的不同的方法比正常的原型構建通過clone()的對象繼承的這種實現是如何工作的?

BaseClass.prototype = new Superclass(); 

他所做的事是這樣的:

function clone(obj) { 
    function F() { } 
    F.prototype = obj; 
    return new F(); 
} 

,然後建立繼承這樣的:

function Child() { } 
Child.prototype = clone(Parent.prototype); 

有人可以解釋這種繼承的兩部分方法,它有什麼好處給出了上面簡單的單線程方法?

編輯:我從意見中瞭解到,現在有一個標準Object.create(),基本上解決了與clone()方法相同的目的,但clone()這個實現如何工作?

+1

因爲'new Superclass()'可能會觸發不希望的副作用,'clone'會給你一個繼承父對象的對象,但不必調用構造函數。 ,現在有一個JavaScript的標準方法來做到這一點,它是'Object'。create()' –

+0

你的例子中的'clone'函數與Object.create'具有相同的用途,這就是爲什麼鏈接問題的答案會(希望)對你有幫助的原因。 –

+0

@CrazyTrain如果'new Superclass()'被調用,會發生什麼* sideeffects *? – Geek

回答

0

這是一個有趣的問題。你提供的代碼片段(克隆函數)被道格拉斯克羅克福德稱爲「原型繼承」,並被描述爲in this article on his website.這種模式變得流行,並在ECMA script 5 into Object.create(), if you look at specification of object create中被正式化,它與Crockford函數的規範完全相同。 它這樣使用:

var Animal = { 
    species: "mammal", 
    noises: function() { 
     console.log("makes noises") 
    }, 
    actions: ["roll back", "jump up"] 
} 

var Cat = Object.create(Animal); 
Cat.name = "blacky" 
Cat.miau = function() { 
    console.log("miau miau"); 
} 

克羅克福德也稱這種差別的產業,因爲定義子類的新屬性,當您只需指定子類和超類之間的差異。貓現在有自己的財產「名」和自己的方法「miau」。

我認爲這樣做的主要問題是您仍然在實例之間共享參考值,例如數組。

如果我們這樣做:

var Cat2 = Object.create(Animal); 
Cat2.actions.push("bite Henry"); 
Cat2.actions 
["roll back", "jump up", "bite Henry"] 
Cat.actions 
["roll back", "jump up", "bite Henry"] 

但至少情況基本屬性不共享這是罰款。

Cat2.name 
undefined 
Cat.name 
"blacky" 
0

說明爲什麼要使用的Object.create或輔助函數來設置原型繼承請看下面的代碼:

function Hamster(name){ 
    if(name === undefined){ 
    throw new Exception("Name cannot be undefined"); 
    } 
    this.name=name; 
}; 

function RussionMini=function(name){ 
    Hamster.apply(this,arguments); 
}; 
RussionMini.prototype=new Hamster();//throws Error 

你可以做RussionMini.prototpe=new Hamster("dummyvalue");但如果一個值必須當你聲明你的對象時(像一個DOM元素),這是不可用的。您仍然可以傳遞一個虛擬對象,但它會讓您的代碼在重構時更加複雜且更容易中斷。當您使用的Object.create(Parent.prototype)

兩個例子都沒有修prototype.constructor所以this.constructor將指向錯誤的函數(也發生;`

更多關於繼承,使用重載函數和原型構建函數可以在這裏找到:Prototypical inheritance - writing up