有人可以向我解释使用Me.prototype.constructor = Me;和为什么需要,当这段代码工作时没有它?
在代码中,在Me对象上创建对象并将其实例化并替换旧的原型对象.为什么我需要在给定代码中指向Me构造函数?
function Me(){
this.name = 'Dejan';
}
function You(){
this.name = 'Ivan';
}
Me.prototype = new You();
somebody = new Me();
Me.prototype.constructor = Me; // Why?
Me.prototype.foo = function(){
alert('Proto Me!'); // It always fire up this alert, ether constructor is pointing to Me or not... !
}
You.prototype.foo = function(){
alert('Proto You!');
}
somebody.foo();
alert(somebody.name); // Alert 'Dejan'
Run Code Online (Sandbox Code Playgroud)
chj*_*hjj 11
它不是必需的,甚至不需要instanceof与普遍的看法相反(instanceof内部检查原型链并且不需要构造函数属性).通常,constructor它本身就是构造函数的非可枚举属性prototype.因此,给予由该构造函数实例化的任何对象,一个不可枚举的constructor属性,指向该构造函数.
如果你需要,最好把它放在那里,理想情况下是不可枚举的.一些代码将假设存在.constructoron对象.
在你的代码贴出来,是的,做继承时的方式,有必要重新构造(如果你想在那里),因为你实例化对象来充当孩子的原型有一个constructor属性指向了错误的构造函数(它的构造).
在ES5中,您可以:
Child.prototype = Object.create(Parent.prototype, {
constructor: { value: Child, enumerable: false }
});
Run Code Online (Sandbox Code Playgroud)
编辑:另外,可能是值得一提的,使用非标准做继承时__proto__,就没有必要重新构造,因为__proto__仅仅规定和对象的原型,它说哪,在其中,当自己的财产没有按"查找将要执行的对象存在.一个新的prototype将永远有一个叫做的属性constructor.
这样做:
var child = function() {};
child.prototype.__proto__ = parent.prototype;
Run Code Online (Sandbox Code Playgroud)
您不必设置构造函数,因为child.prototype的基本构造函数属性仍然存在.如果访问,则不需要执行原型链查找.
如果你更换线
Me.prototype.constructor = Me; // Why?
Run Code Online (Sandbox Code Playgroud)
同
console.log(Me.prototype.constructor);
Me.prototype.constructor = Me; // Why?
Run Code Online (Sandbox Code Playgroud)
你会发现在设置它之前,Me.prototype.constructor是You因为这Me.prototype是一个You由于线路的实例
Me.prototype = new You();
Run Code Online (Sandbox Code Playgroud)
所以,// Why?评论这一行是必要的,以"修复"这种错误的印象,即你通过这种方式进行继承而给出了JavaScript.
本质上问题是因为您尝试使用原型继承来实现经典继承.原型继承工作的对象实例,并没有"阶级",甚至,真的,概念"类型",但JavaScript的让事情额外的混乱与整个new,.constructor和instanceof业务.
做这种事情的一种更原型的方法是避免构造函数支持幂构造函数,即返回具有所需形式的对象的函数:
function begetPart(partNumber, description) {
return Object.create({}, {
number: { value: partNumber },
description: { value: description },
describe: {
value: function () {
alert(this.description);
}
}
});
}
function begetTire(partNumber, speed) {
return Object.create(
begetPart(partNumber, "A tire"),
{
speed: { value: speed },
describe: {
value: function () {
alert(this.description + "; speed = " + this.speed);
}
}
}
);
}
var genericPart = begetPart(1234, "A widget");
genericPart.describe(); // alerts "A widget"
var tire = begetTire(4567, "fast");
tire.describe(); // alerts "A tire; speed = fast"
Run Code Online (Sandbox Code Playgroud)
这里我们用Object.create来说"基于这个其他对象实例创建一个对象实例".另一个实例是一个新的空对象,begetPart以及一个预先填充了一些属性的新"部分实例" begetTire.
这更好地反映了JavaScript和原型继承实际上是如何工作的,因为在原型继承中,对象实例继承自其他对象实例,而没有整个"类型"或"类"的想法妨碍.