原型对象的构造函数属性

时间:2013-12-17 21:28:00

标签: javascript inheritance constructor prototypal-inheritance

请考虑以下代码段:

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()构造函数吗?

3 个答案:

答案 0 :(得分:1)

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属性。这是在构造它时直接在实例上设置的,并且它不是从原型继承的。

答案 1 :(得分: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
  6. 这将永远持续下去。相反,你想要的是Object.getPrototypeOf

    1. Object.getPrototypeOf(benji).constructorDog
    2. Object.getPrototypeOf(Object.getPrototypeOf(benji)).constructorObject
    3. 由于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 :(得分:0)

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

Dog.prototype.tail = true;