它似乎與註釋掉的行一起工作的原因是該註釋行中的myChildClass
是函數;但在myChildClass
構造函數中的行中,this
不是函數,它是由new
運算符創建的實例。功能上的prototype
屬性是由new
運算符將其創建的新實例指定爲其基礎原型的對象; 實例上的prototype
屬性沒有特別的含義(例如,它不是指實例的基礎原型)。
正確的方式做,這是這樣的:
// Parent constructor
function myMotherClass(value){
this.MyValue = value
}
// Child constructor
function myChildClass(value){
// Chain to parent constructor, passing any necessary args
myMotherClass.call(this, value);
// Other child stuff -- see note below
this.alert = function(){
alert(value);
};
}
// Set up inheritance by creating myChildClass's prototype
// property to be an object that is baked by myMotherClass's
// prototype object; do NOT *call* myMotherClass here, it's
// a common anti-pattern you'll see in a lot of examples
inherit(myMotherClass, myChildClass);
// Create an instance
var myClass = new myChildClass(2);
myClass.alert();
...其中inherit
是:
function inherit(parent, child) {
var temp;
if (Object.create) {
child.prototype = Object.create(parent.prototype);
} else {
temp = function() { };
temp.prototype = parent.prototype;
child.prototype = new temp();
}
child.prototype.constructor = child;
}
注意與你定義alert
的方式,出現這種略顯怪異的行爲:
var o = new myChildClass(42);
console.log(o.MyValue); // 42
o.alert(); // alerts "42"
o.MyValue = 67;
console.log(o.MyValue); // 67
o.alert(); // alerts "42" <== !!!
您可以更改如何定義alert
所以它使用MyValue
這樣的:
this.alert = function() {
alert(this.MyValue);
};
...只要你總是把它通過實例。 (更多關於我的博客:神話方法)
但是,如果你要做到這一點,你可以把它移到原型 - 把這個inherit
調用樹立鏈後:
myChildClass.prototype.alert = function(){
alert(this.MyValue);
};
這裏是所有放在一起:
// Parent constructor
function myMotherClass(value){
this.MyValue = value
}
// Child constructor
function myChildClass(value){
// Chain to parent constructor, passing any necessary args
myMotherClass.call(this, value);
// Other child stuff...
}
// Set up inheritance by creating myChildClass's prototype
// property to be an object that is baked by myMotherClass's
// prototype object; do NOT *call* myMotherClass here
inherit(myMotherClass, myChildClass);
// Add stuff to myChildClass's prototype property
myChildClass.prototype.alert = function(){
alert(this.MyValue);
};
// Create an instance
var myClass = new myChildClass(2);
myClass.alert();
如果你有興趣在JavaScript中經典的繼承,我有一個方便的輔助腳本,Lineage
,這使得上述簡單,增加了一些有用的FEA tures:http://code.google.com/p/lineagejs/
通常OP所發佈的例子的類型是通過使用''constructor''和''''prototype''來實現的請參考[JavaScript中的古典繼承](http://www.crockford.com/javascript /inheritance.html)。 – sarbbottam
請參閱[在函數構造函數中設置原型](http:// stackoverflow。com/questions/16582608/setting-prototypes-inside-function-constructor)幾乎重複的討論。 –
@sarbbottam:除了在那篇文章中,Crockford在創建子構造器的原型時調用父構造器是一個經典的錯誤,這是一種反模式,甚至不能在他的例子中正常工作('Parenizor'預計接收一個'value'參數,但是'ZParenizor.inherits(Parenizor);'調用'Parenizor''沒有'[在inherits'內]]。 –