Javascript 更改构造函数的问题';s原型
我正在阅读斯托扬·斯特凡诺夫的书《面向对象的JavaScript》,我偶然发现了一个有趣的问题。代码如下:Javascript 更改构造函数的问题';s原型,javascript,Javascript,我正在阅读斯托扬·斯特凡诺夫的书《面向对象的JavaScript》,我偶然发现了一个有趣的问题。代码如下: var shape = { type: 'shape', getType: function() { return this.type; } }; function Triangle(a, b, c) { this.a = a; this.b = b; this.c = c; this.type = 'triangl
var shape = {
type: 'shape',
getType: function() {
return this.type;
}
};
function Triangle(a, b, c) {
this.a = a;
this.b = b;
this.c = c;
this.type = 'triangle';
}
Triangle.prototype = shape; // changing the prototype object
Triangle.prototype.getPerimeter = function() {
return this.a + this.b + this.c;
}
var t = new Triangle(1, 2, 3);
t.constructor; // logs Object() instead of Triangle(a, b, c)
如您所见,这里是一个简单的构造函数示例,它从prototype对象中继承了一些属性。但是对象t的构造函数属性指向object()对象,而不是它应该指向的三角形(a,b,c)。不过,如果我用原型更改来评论这一行,一切都很好。我有什么问题?
(重读面向对象Javascript和Javascript模式的整个原型章节,找不到答案)。
另外,很抱歉我的英语不好,正在努力练习。:) 奇怪的是,“constructor”属性没有引用该对象的构造函数。相反,它指的是对象原型的构造函数
是Mozilla的相关文档页。
形状是一个对象,因此通过执行此操作:
Triangle.prototype = shape;
将三角形
构造函数更改为对象
形状不是构造函数,而是对象。它的构造函数是对象构造函数
如果shape是一个构造函数,那么您可以设置
三角形。原型=新形状
和Triangle.prototype.constructor=Triangle,以覆盖您刚才设置的shape.prototype.constructor。我将分两部分解释您的代码。首先,构造函数
属性实际上是什么?其次,为什么它不在代码中返回对象
构造函数
属性和斯托扬的错误:
在斯托扬·斯特凡诺夫的书p150中,他指出:
prototype是定义函数后立即创建的属性其初始值为空对象。
这是错误的。根据第9.2节
原型属性的初始值是具有单个属性的对象此属性名为constructor,并返回与原型关联的构造函数
您可以使用Triangle.prototype.constructor
对其进行测试。它是在定义函数时设置的
结论1:构造函数
实际上是构造函数的属性。原型
。在您的例子中,它是Triangle.prototype.constructor
Triangle
的所有实例都可以通过原型链访问此属性但是这些对象本身没有构造函数
属性。下面的代码证明了这一点:
function Triangle(a, b, c) {
this.a = a;
this.b = b;
this.c = c;
this.type = 'triangle';
}
var t = new Triangle(1, 2, 3);
t.hasOwnProperty('constructor');
>>false
t.__proto__.hasOwnProperty('constructor');
>>true
结论2:当您访问实例的构造函数
属性时,您可以从原型链获取它们
为什么它没有像你期望的那样工作
您将Triangle.prototype
设置为shape
,该不包含原始构造函数
属性
因此,这一次,当您查询t.constructor
时,它将在以下过程中解析它:
查看它自己的属性,发现没有constructor
继续查找t.\uuuuu proto\uuuu
,即Triangle.prototype
。您已将其设置为shape
,它不包含构造函数
属性
继续沿着原型链向上查找-t.\uuuuu proto\uuuu.\uuuuuu proto\uuuu
。它是Triangle.prototype.\uuuu proto\uuuu
,它被解析为Object.prototype
<代码>对象。原型
具有构造函数
属性,它引用对象
在这里的示例中,基本上使用的是本机/基于类的继承。 在Javascript中,(据我所知),当您使用
new
关键字时,您将创建一个带有构造函数和附加原型对象的函数对象
执行此操作时:
Triangle.prototype = shape;
您重写构造函数方法。您可以使用控制台在将形状指定给Triangle.prototype
之前和之后观察对象
然后执行此操作时:
t.constructor;
当调用构造函数方法在原型链中找到构造函数方法时,您无法查看您希望看到的内容
var形状={
键入:“形状”,
getType:函数(){
返回此.type
}
}
函数三角形(a,b,c){
this.type='triangle'
这个a=a;
这个.b=b;
这个.c=c;
}
三角形。原型=形状;
Triangle.prototype.constructor=三角形;
Triangle.prototype.GetPermission=函数(){
归还这个。a+这个。b+这个。c
}
var t=新三角形(1,2,3)
console.log(t.constructor==Triangle)//true
console.log(shape.isPrototypeOf(t))//true
console.log(t.getPermission())//6
console.log(t.getType())//triangle
当然,我怎么会忘记读过它呢。应该多练习而不是阅读。:)proto是隐藏属性,未在js规范中定义,不受支持。使用它是不安全的。请不要只发布代码作为答案,还要解释代码的作用以及如何解决问题。带有解释的答案通常更有帮助,质量更好,更容易吸引选票。