對於那些不熟悉,替代繼承如下所示:爲什麼「替代」繼承關閉停止工作?
var Surrogate = function() {}
var extend = function (Base, Sub) {
Surrogate.prototype = Base.prototype;
Sub.prototype = new Surrogate();
Sub.prototype.constructor = Sub;
}
var Animal = function (name) {
this.name = name;
};
Animal.prototype.speak = function() {
return this.getSound() + ' ' + this.name;
};
Animal.prototype.getSound = function() {
// Abstract
};
var Cat = function (name) {
Animal.call(this, name);
};
extend(Animal, Cat);
Cat.prototype.getSound = function() {
return 'Meow';
};
var kitty = new Cat('Maru');
console.log(kitty.speak()); // Logs "Meow Maru"
console.log(kitty instanceof Animal); // Logs true
console.log(kitty instanceof Cat); // Logs true
console.log(kitty.constructor == Cat); // Logs true
基本上建立從Animal
繼承的構造函數中,我們創建另一個構造函數(在這種情況下,Cat
),調用Animal
構造函數使用this
的適當值,然後使用extend
函數將Cat
的原型設置爲沒有name屬性的Animal
的「實例」。考慮使用extend(Animal, Cat)
與Cat.prototype = new Animal()
相同,除了Cat.prototype.name
未定義。
以上工作完美,我稍後有一個側面問題。
我想採取一個新的水平,並隱藏Surrogate
封閉裏面,所以我改變了Surrogate
和extend
的聲明看起來像這樣:
var extend = (function() {
var Surrogate = function() {};
return function (Base, Sub) {
Surrogate.prototype = Base.prototype;
Sub.prototype = new Surrogate();
Sub.prototype.constructor = Sub;
};
});
現在,當我運行該腳本失敗上第一個日誌聲明:
TypeError: Object [object Object] has no method 'speak'
但是,創建另一個文件extend.js
具有以下內容:
var Surrogate = function() {};
module.exports = function (Base, Sub) {
Surrogate.prototype = Base.prototype;
Sub.prototype = new Surrogate();
Sub.prototype.constructor = Sub;
}
並將主腳本中extend
的聲明更改爲var extend = require('./extend');
作品,並且Surrogate
按預期隱藏。
對於主要問題:據我所知,節點和其他CommonJS系統只是將模塊封裝在閉包函數中,就像我最初試圖做的那樣。爲什麼模塊版本可以工作,但是我的版本與閉包不兼容?
對於上面提到的側面問題:我很驚訝Sub.prototype.constructor = Sub
。我認爲它應該是Sub.prototype.constructor = Base
,但導致最後的日誌記錄語句記錄爲false
。我想我已經爲自己回答了這個問題,但我認爲constructor
是構建對象上的一個屬性,而不是原型。這是否是另一種方式?
UPDATE
我只是試圖與使用一種稱爲extend
定義模塊AMD如下:
define(function() {
var Surrogate = function() {};
return function (Base, Sub) {
Surrogate.prototype = Base.prototype;
Sub.prototype = new Surrogate();
Sub.prototype.constructor = Sub;
};
});
它完美的罰款。我覺得我在這裏忽略了一件極其簡單的事......爲什麼在模塊系統中工作正常,而不是在普通的關閉中工作?我測試了node.js,Chrome和Firefox中的所有版本(純文本,閉包和模塊)。
沒錯。返回一個函數返回一個函數... – ErikE
ALBHALBHAFHLASHD。我不能相信我錯過了那些parens ...... – user1937128
雅,它看起來像你甚至有可能在一個點上:p – goat