3

這是一個非常古老的主題,寫了很多東西,但我還沒有找到它的真正原因,所以請耐心等待。javascript中的繼承模式

已經花了一點時間,試圖讓我的頭圍繞在JavaScript中newf.prototype構造結構,並閱讀關於它如何是一個原型的語言,更何況Crockford的關於這個問題的照明意見後,我得出一個結論下列是一個更自然的方式來模擬傳統的基於類的繼承在JavaScript中,應該想:

// emphasise that there's no superclass instead of writing A = {} 
var A = Create.object(null); 

// define the 'instance initializer', which half of what a constructor is 
A.init = function(x, y) { 
    this.x = x; 
    this.y = y; 
    return this; 
} 

// a method 
A.sum = function() { 
    return this.x + this.y; 
} 

// instantiate A 
var a = Object.create(A).init(3); 

// a subclass 
var B = Object.create(A); 

B.init = function(x, y, w) { 
    A.init.call(this, x, y); 
    this.w = w; 
    return this; 
} 

B.weightedSum = function() { 
    return (1.0 - this.w) * this.x + this.w * this.y; 
} 

// instantiate B 
var b = Object.create(B).init(1, 2, 0.3); 

// equivalent of `instanceof` 
var bInstanceOfA = A.isPrototypeOf(b); 

我喜歡這是它暴露到底發生了什麼,因爲是對象之間的明確分工創建(適用於實例化和子類化)和初始化(僅適用於實例化)。創建基類和子類也有對稱性。代碼不需要外部定義的函數或庫,但也不是特別詳細。

因此,我的問題如下:那些對JavaScript有更多經驗的人能否告訴我,我不考慮這種方法是否存在問題,或者它是否是一種好的模式?

+1

['的Object.create()'](https://開頭developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/create#Cross-browser_compatibility)只適用於IE> = 9。 –

+0

非常感謝...我相信這應該是相當直接的如果想要添加它?我主要在節點編程,所以它不是我主要關心的問題。還有什麼問題? – ehremo

+0

無論如何,Object.create()有一個[polyfill](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/create#Polyfill)。但是這種方法不能使用'new'關鍵字。這擴展了對象,而不是原型。 –

回答

0

用這種方法丟失了new關鍵字。所以你不能說new A(128, 256)

但是你可以使用Object.create()爲原型繼承並以這種方式創建new關鍵字的規則物體:

var Employee = function(name) { 
    this.name = name; 
    return this; 
}; 

Employee.prototype = { 
    doWork: function() { 
     console.log('%s is doing some abstract work', this.name); 
    } 
}; 

var Driver = function(name) { 
    return Employee.call(this, name); 
}; 

Driver.prototype = Object.create(Employee.prototype, { 
    doWork: { 
     value: function() { 
      console.log('%s is driving a car', this.name); 
     } 
    }, 
    fixEngine: { 
     value: function() { 
      console.log('%s is fixing an engine', this.name); 
     } 
    } 
}); 

var employee = new Employee('Jim'); 
var driver = new Driver('Bill'); 

employee.doWork(); // Jim is doing some abstract work 
driver.doWork(); // Bill is driving a car 
driver.fixEngine(); // Bill is fixing an engine 

http://jsfiddle.net/f0t0n/HHqEQ/

+0

那麼這就是我的觀點,我不希望能夠使用'new'關鍵字,因爲它感覺就像是一種語言功能,它被標記爲使JavaScript看起來像它有類。我的模式提醒你,就JavaScript而言,實例只是初始化的子類(或者子類是未初始化的實例:D)。 'new'關鍵字掩蓋了這種對稱性。 – ehremo