Javascript JS中原型构造函数的使用
有人能给我解释一下Javascript JS中原型构造函数的使用,javascript,oop,Javascript,Oop,有人能给我解释一下me.prototype.constructor=me的用法吗以及为什么需要,当此代码正在运行且没有它时 在代码中,原型对象是在Me对象上创建的,它被实例化并替换为旧的原型对象。为什么我需要在给定的代码中指向我的构造函数 function Me(){ this.name = 'Dejan'; } function You(){ this.name = 'Ivan'; } Me.prototype = new You(); somebody = new M
me.prototype.constructor=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'
与流行的观点相反,instanceof
甚至不需要它(instanceof在内部检查原型链,不需要构造函数属性)。通常,构造函数
本质上是构造函数的原型
上的不可枚举属性。因此,为该构造函数实例化的任何对象提供一个指向该构造函数的不可枚举的构造函数
属性
如果需要,最好把它放在那里,理想情况下是不可枚举的。某些代码将假定对象上存在.constructor
在您发布的代码中,是的,当以这种方式执行继承时,有必要重置构造函数(如果您想重置构造函数),因为您实例化作为子原型的对象具有指向错误构造函数(其构造函数)的构造函数属性
在ES5中,您将执行以下操作:
Child.prototype = Object.create(Parent.prototype, {
constructor: { value: Child, enumerable: false }
});
编辑:另外,可能值得一提的是,当使用非标准的\uuuuuuu proto\uuuuuuu
执行继承时,不需要重置构造函数,因为\uuuuuuuu proto\uuuuu
仅指定和对象的原型,也就是说,当自己的属性不存在时将对其执行查找的对象。新的原型
将始终具有名为构造函数
的属性
这样做:
var child = function() {};
child.prototype.__proto__ = parent.prototype;
您不必设置构造函数,因为child.prototype的基本构造函数属性仍然存在。如果访问,则无需执行原型链查找。如果您更换该行
Me.prototype.constructor = Me; // Why?
与
在设置它之前,您会发现,Me.prototype.constructor
是you
,因为Me.prototype
是you
的一个实例,这是由于行的原因
Me.prototype = new You();
因此,带有//Why?
注释的行对于“修复”这种错误印象是必要的,即您通过这种方式继承JavaScript
从本质上讲,问题的产生是因为您试图使用原型继承来实现经典继承。原型继承适用于对象实例,没有“类”的概念,甚至没有“类型”的概念,但是JavaScript使事情与整个新的,.constructor
,以及业务的实例更加混淆
做这类事情的一种更典型的方式是避开构造函数而使用幂构造函数,即返回具有所需形式的对象的函数:
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"
这里我们使用Object.create
来表示“基于这个其他对象实例创建一个对象实例”。另一个实例是begetPart
的一个新的空对象,以及一个新的“part实例”,其中预填充了begetTire
的一些属性
这更好地反映了JavaScript和原型继承实际上是如何工作的,因为在原型继承中,对象实例继承自其他对象实例,而没有整个“类型”或“类”想法碍事。我相信传统浏览器会检查instanceof
关键字的constructor
属性。你确定IE6没有检查constructor
属性吗?和Object.create
为您设置constructor
属性。不,我不确定IE6,因为我并不真正关心IE6。另外,Object.create并没有为您设置构造函数,它没有构造函数的概念,事实上,这就是Object.create的要点。您只能获得与父构造函数相等的构造函数属性,这对于继承来说是错误的。所以你需要改变它。你的权利我对构造函数的看法不好。Object.create没有构造函数的概念
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"