如何在javascript中显示委托的`constructor`引用问题?

时间:2013-05-14 15:52:28

标签: javascript

在下面的例子中,我注意到注释“修复了委托的构造函数引用”,我很好奇 - 在添加javascript行后,我可以显示“不工作/然后工作吗?”

这里的全部要点=> https://gist.github.com/getify/5572383

提前谢谢

function Foo(who) {
    this.me = who;
}

Foo.prototype.identify = function() {
    return "I am " + this.me;
};

function Bar(who) {
    Foo.call(this,"Bar:" + who);
}

Bar.prototype = Object.create(Foo.prototype);
Bar.prototype.constructor = Bar;    // "fixes" the delegated `constructor` reference

1 个答案:

答案 0 :(得分:6)

javascript中的函数实际上是对象。当我们在Javascript中创建任何函数Foo时,解释器会自动创建一个prototype属性Foo.prototype,它本身就是一个对象。然后,解释器在此对象上创建constructor属性,该属性引用Foo本身:

console.log(Foo.prototype.constructor);                   // reference to Foo;
console.log(Foo.prototype.hasOwnProperty("constructor")); // TRUE;

当我们创建Bar函数时,会发生同样的过程。但后来我们引入了一个区别。不同之处在于我们使用以下代码手动覆盖Bar.prototype处的对象:

Bar.prototype = Object.create(Foo.prototype);

现在Bar.prototype有一个我们手动创建的新对象。这个新对象没有constructor属性,因为它是由我们而不是解释器创建的:

console.log(Bar.prototype.hasOwnProperty("constructor")); // FALSE

因此Bar.prototype没有自己的constructor属性,Foo.prototype属性。接下来,假设我们创建了Bar

的实例
var myBar = new Bar();

myBar.constructormyBar对象上不存在的继承属性。如果我们尝试访问它,javascript解释器会在原型链中搜索constructor属性。它在Bar.prototype上找不到,因为我们覆盖了该对象。解释器继续搜索并最终在Foo.prototype上找到该属性。因此,对myBar.constructor的任何引用都会引用Foo.prototype.constructor,其中包含对Foo的引用:

console.log(myBar.constructor); // reference to Foo

因此,这就是我们手动明确设置Bar.prototype.constructor的原因,以便在遍历原型链时,解释器会在constructor上找到Bar.prototype属性,如果我们没有'覆盖它:

Bar.prototype.constructor = Bar;

最终结果是对我们的对象更有用的行为:

var myBar2 = new Bar();
console.log(myBar2.constructor); // reference to Bar

这个问题不应该经常出现,因为人们需要检查对象的constructor属性是很少见的。