【问题标题】:constructor property of a prototype object原型对象的构造函数属性
【发布时间】:2013-12-17 21:27:59
【问题描述】:

考虑以下 sn-p:

function Dog(){this.tail = true;}
var benji = new Dog();
var rusty = new Dog();
Dog.prototype.say = function(){return 'Woof!';}
alert(benji.say()); // this alerts woof!
alert(rusty.say()); // this alerts woof!
alert(benji.constructor.prototype.constructor); // THIS ALERTS THE DOG FUNCTION
alert(typeof benji.constructor.prototype.tail) // THIS ALERTS UNDEFINED

为什么benji.constructor.prototype.constructor alert 狗会起作用? 不应该是Object()构造函数吗?

【问题讨论】:

  • benji.constructor == Dog 只是因为Dog.prototype.constructor = Dog
  • tail 是一个特定于实例的成员,并且说是一个原型(共享)成员,更多关于原型和构造函数的信息在这里:*.com/a/16063711/1641941

标签: javascript inheritance constructor prototypal-inheritance


【解决方案1】:

很简单:

+-----------------+       tail
|                 |-----------------> [true]
|      benji      |
|                 |
+-----------------+
         |
         | __proto__
         |
         v
+-----------------+    constructor    +-----------------+
|                 |------------------>|                 |
|  Dog.prototype  |                   |       Dog       |
|                 |<------------------|                 |
+-----------------+     prototype     +-----------------+
         |
         | __proto__
         |
         v
+-----------------+    constructor    +-----------------+
|                 |------------------>|                 |
| Object.prototype|                   |      Object     |
|                 |<------------------|                 |
+-----------------+     prototype     +-----------------+
  1. benji.constructorDog
  2. benji.constructor.prototypeDog.prototype
  3. benji.constructor.prototype.constructorDog
  4. benji.constructor.prototype.constructor.prototypeDog.prototype
  5. benji.constructor.prototype.constructor.prototype.constructorDog

这将永远持续下去。相反,你想要的是Object.getPrototypeOf:

  1. Object.getPrototypeOf(benji).constructorDog
  2. Object.getPrototypeOf(Object.getPrototypeOf(benji)).constructorObject

由于Object.getPrototypeOf 被迭代,您可以为其创建一个特殊函数:

function getPrototypeOf(n, object) {
    if (n === 0) return object;
    else return getPrototypeOf(n - 1, Object.getPrototypeOf(object));
}

现在你可以按如下方式使用它:

getPrototypeOf(1, benji).constructor; // Dog
getPrototypeOf(2, benji).constructor; // Object

就是这样。

【讨论】:

  • 帮助很大!谢谢!
【解决方案2】:

benji.constructor 解析为 Dog。请注意benji 实际上并没有它自己的constructor 属性:它从其原型继承constructor 属性。 benji.constructor 真的是Dog.prototype.constructor,就像benji.say 真的是Dog.prototype.say

因此,benji.constructor.prototype 实际上是Dog.prototype,这是benji 继承原型属性的原型。

因此,最后,benji.constructor.prototype.constructor 真的是Dog.prototype.constructor,与benji.constructor 相同。

相比之下,benji 确实拥有自己的 tail 属性。是在构造实例时直接设置的,不是从原型继承的。

【讨论】:

    【解决方案3】:

    这是因为Dog 的原型不包含该属性。相反,您在构造函数中为每个新实例设置它。要在原型中包含 tail,您必须在那里定义它:

    Dog.prototype.tail = true;
    

    【讨论】: