3

在下面的示例中,我注意到注释“修复了委托的构造函数引用”,我很好奇 - 如何在添加该行 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
4

1 回答 1

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.constructor是对象上不存在的继承属性myBar。如果我们尝试访问它,javascript 解释器会在原型链中搜索该constructor属性。它没有找到一个,Bar.prototype因为我们覆盖了那个对象。解释器继续搜索并最终在 上找到属性Foo.prototype。因此,任何对 的引用都myBar.constructor将引用Foo.prototype.constructor,其中包含对 的引用Foo

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

所以这就是我们显式Bar.prototype.constructor手动设置的原因,这样当遍历原型链时,解释器会找到一个constructor属性 on Bar.prototype,就像我们没有覆盖它一样:

Bar.prototype.constructor = Bar;

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

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

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

于 2013-05-14T16:15:28.230 回答