javascript - 更改构造函数原型(prototype)的问题

标签 javascript

我目前正在阅读 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)

如您所见,这是构造函数从原型(prototype)对象继承一些属性的简单示例。但是对象 t 的构造函数属性指向 Object() 对象而不是 Triangle(a, b, c),它应该有。但是,如果我对原型(prototype)更改的行进行评论,则一切正常。我的问题是什么? (重新阅读面向对象的 Javascript 和 JavaScript 模式中的整个原型(prototype)章节,找不到答案)。 附言抱歉我的英语不好,正在努力练习。 :)

最佳答案

我将分两部分解释您的代码。首先,什么是 constructor属性(property)实际上?其次,为什么不返回 Objects在你的代码中?

constructor属性(property)和斯托扬的错误:

在 Stoyan Stefanov 的书 p150 中,他说:

prototype is a property that gets created as soon as you define the function. Its initial value is an empty object.

这是错误的。根据JavaScript Definitive Guide 9.2节

The initial value of the prototype property is an object with a single property. This property is named constructor and refers back to the constructor function with which the prototype is associated.

您可以使用 Triangle.prototype.constructor 对其进行测试.定义函数的时候就设置好了。

结论 1:constructor实际上是 Constructor.prototype 的属性(property).在您的情况下,它是 Triangle.prototype.constructor .

Triangle 的所有实例可以通过原型(prototype)链访问这个属性。 但是这些对象本身没有constructor属性(property)。下面的代码证明了这一点:

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实例的属性,您可以从原型(prototype)链中获取它们。

为什么它没有像您预期的那样工作

你设置Triangle.prototypeshape其中包含原始constructor属性(property)。

因此,这一次,当您查询 t.constructor , 它将在以下过程中解决它:

  1. 查看它自己的属性,发现没有constructor
  2. 继续关注t.__proto__ ,即 Triangle.prototype .您已将其设置为 shape其中不包含 constructor属性(property)。
  3. 继续沿着原型(prototype)链查找 - t.__proto__.__proto__ .是Triangle.prototype.__proto__ , 解析为 Object.prototype . Object.prototypeconstructor属性(property),它指的是Object .

关于javascript - 更改构造函数原型(prototype)的问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6192921/

相关文章:

javascript - 如何使用单击和切换来更新变量值

javascript - 如何同步多个可手动水平滚动

javascript - 当指令手动替换元素的内容时,ngRepeat 不会删除旧条目

c# - 你如何在 C# 中获取用户的国家/地区名称?

javascript - 砖石堆叠在一起,直到在 Wordpress 上调整页面大小

javascript匹配()错误

javascript - 通过 jQuery 访问 Flash 函数

javascript - 无法使用 Cheerio 获取 iframe

javascript - 为什么each()遍历数组后就结束了?

javascript - for+if 循环帮我解决了一些问题