更改构造函数原型时出现问题
Problems with changing constructor's prototype
我目前正在阅读Stoyan Stefanov的书"面向对象的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 = '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)
如您所见,下面是构造函数从原型对象中固有某些属性的简单示例。但是对象 t 的构造函数属性指向 Object(( 对象,而不是 Triangle(a, b, c(,因为它应该有。但是,如果我在原型更改中评论该行,则一切正常。我的问题是什么?(重读面向对象的Javascript和JavaScript模式中的整个原型章节,找不到答案(。附言对不起我的英语不好,试图练习它。:)
我将分两部分解释您的代码。首先,constructor
属性实际上是什么?其次,为什么它不在你的代码中返回Objects
?
constructor
属性和斯托扬的错误:
在斯托扬·斯特凡诺夫(Stoyan Stefanov(的书第150页中,他说:
原型是定义函数后立即创建的属性。其初始值为空对象。
这是错误的。根据 JavaScript 权威指南第 9.2 节
原型属性的初始值是具有单个属性的对象。此属性名为构造函数,并引用与原型关联的构造函数。
您可以使用 Triangle.prototype.constructor
.它是在定义函数时设置的。
结论1:constructor
实际上是Constructor.prototype
的财产。在您的情况下,它是 Triangle.prototype.constructor
.
Triangle
的所有实例都可以通过原型链访问此属性。但这些对象本身没有 constructor
属性。以下代码证明了这一点:
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:当您访问实例的 constructor
属性时,您可以从原型链中获取它们。
为什么它没有按预期工作
将Triangle.prototype
设置为不包含原始constructor
属性的shape
。
因此,这一次,当您查询t.constructor
时,它将在以下过程中解析它:
- 看看它自己的属性,找不到
constructor
- 继续仰望
t.__proto__
,这是Triangle.prototype
。已将其设置为不包含constructor
属性的shape
。 - 继续沿着原型链向上查找 -
t.__proto__.__proto__
.它是Triangle.prototype.__proto__
的,它被解析为Object.prototype
。Object.prototype
具有constructor
属性,它指的是Object
。
奇怪的是,"constructor"属性并不引用该对象的构造函数。相反,它指的是对象原型的构造函数。
这是来自Mozilla的相关文档页面。
shape
是一个对象,所以通过这样做:
Triangle.prototype = shape;
将构造函数更改为Triangle
Object
您在这里的示例中基本上使用了基于本机/类的继承。在 Javascript 中,(根据我的理解(当您使用 new
关键字时,您会创建一个带有构造函数和附加原型对象的函数对象。
执行此操作时:
Triangle.prototype = shape;
重写构造函数方法。您可以使用控制台观察将形状分配给Triangle.prototype
之前和之后的对象。
然后执行此操作时:
t.constructor;
您无法查看预期看到的内容,因为对构造函数方法的调用会在原型链中查找构造函数方法。
是一个构造函数,而是一个对象。它的构造函数是对象构造函数。
如果形状是您可以设置的构造函数
三角形原型=新形状;
和 Triangle.prototype.constructor=Triangle,以覆盖您刚刚设置的 shape.prototype.constructor。
var shape = {
type: 'shape',
getType: function () {
return this.type
}
}
function Triangle(a, b, c) {
this.type = 'triangle'
this.a = a;
this.b = b;
this.c = c;
}
Triangle.prototype = shape;
Triangle.prototype.constructor = Triangle;
Triangle.prototype.getPerimeter = function () {
return this.a + this.b + this.c
}
var t = new Triangle(1, 2, 3)
console.log(t.constructor === Triangle) // true
console.log(shape.isPrototypeOf(t)) // true
console.log(t.getPerimeter()) // 6
console.log(t.getType()) // triangle
- 使用setInterval调用原型函数时出现问题
- 基本对象/原型语法问题
- Javascript继承的问题&基类原型
- JavaScript 将数组推送到类原型问题
- 是否存在替换Javascript构造函数的问题'原型,而不是添加到原型中
- Javascript和原型继承问题
- 实时Magento网站上的原型JS问题
- Magento - 原型.js和jQuery问题 - 添加到购物车按钮
- 使用函数原型的 JavaScript 继承问题
- 对象的价值和原型问题
- Javascript原型继承问题
- 原型遗传的敲除问题
- Javascript:使用原型函数时出现问题
- 选择器原型等库中的“这个”问题
- 这个原型缓冲解码有什么问题
- JS/jQuery 原型设计问题,可能的范围问题
- JavaScript原型,调用函数时出现问题
- node.js中的继承问题:试图覆盖子类的原型时出现赋值错误
- 原型继承的新手-Can'找不到Undefined变量的问题
- javascript的问题"原型"在书签.我需要图书馆吗?