anObject.prototype.constructor有什么作用? [英] What does anObject.prototype.constructor do?

查看:96
本文介绍了anObject.prototype.constructor有什么作用?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

假设我们有这个构造函数:

Suppose we have this constructor:

var Foo = function(){
   this.x = "y";
}

Foo Foo.prototype.constructor 求值为同一个函数,但 Foo.prototype.constructor = function(){this.x =z} 似乎没有改变 new Foo()的结果。但它会改变结果

Foo and Foo.prototype.constructor evaluate to the same function, yet Foo.prototype.constructor = function(){this.x="z"} doesn't seem to change the result of new Foo(). It does however change the result of

var i = new Foo();
i.constructor; // evals to function (){this.x = "z"}

这里发生了什么?我不打算使用这个用于任何事情,我只是对这种语言感到好奇。

What's going on here? I don't plan on using this for anything, I'm just curious about the language.

推荐答案

函数的 prototype 属性的构造函数属性旨在指向函数,以便您可以问一个对象是什么构造它的。它作为创建功能对象的一部分自动设置(参见第13.2节规范)。如您所见,您可以覆盖 Foo.prototype 上的构造函数属性,如果您愿意,可以更改,但默认情况下就是它的用途。

The constructor property of the prototype property of a function is meant to point back to the function so that you can ask an object what constructed it. It's set up automatically as part of creaeting the function object (See Section 13.2 of the spec). As you've seen, you can override the constructor property on the Foo.prototype if you like, to change that, but by default that's what it's for.

有一个很好的理由可以覆盖它,这与继承有关。假设您想要一个 Base 构造函数来创建基础对象,并使用一个派生构造函数来创建具有这些特征的派生对象 Base 以及 Derived 的添加/修改。通常(虽然不是我的想法)你看到完成(没有帮助脚本)的方式是:

There's a good reason you can override it, which relates to inheritance. Suppose you want to have a Base constructor that creates base objects, and a Derived constructor that creates derived objects with the features of Base plus the additions/modifications of Derived. The usual (though not to my mind ideal) way you see that done (absent helper scripts) is:

function Base() {
}
Base.prototype.foo = function() {
    console.log("I'm Base#foo");
};

function Derived() {
}
Derived.prototype = new Base(); // So we get all the `Base` stuff
Derived.prototype.bar = function() {
    console.log("I'm Derived#bar");
};

var d = new Derived();
d.foo(); // "I'm Base#foo"
d.bar(); // "I'm Derived#bar"

现在的问题是, d.constructor === Base 而不是 Derived 。因此能够解决这个问题非常重要:

The problem is that now, d.constructor === Base rather than Derived. So being able to fix that is important:

...
Derived.prototype = new Base();          // So we get all the `Base` stuff
Derived.prototype.constructor = Derived; // Fix up
...

(旁注:所有这些管道&mdash&mdash ;以及围绕超级呼叫的复杂性—为什么这么多人为此创建了帮助脚本,包括(咳嗽) 我的。)

(Side note: All of this plumbing — and complexity around supercalls — is why so many people have created helper scripts for this, including (cough) mine.)

请注意,上述内容并非属于设置继承层次结构的理想方法。这是你经常看到的,但正如我上面所说,并不理想。为了完整起见,这是更好的:

Note that the above is not meant to be an ideal way to set up inheritance hierarchies. It's what you usually see, but as I said above, not ideal. Just for completeness, this is better:

function Base() {
}
Base.prototype.foo = function() {
    console.log("I'm Base#foo");
};

function Derived() {
    Base.call(this); // So Base sets up its stuff
}
Derived.prototype = Object.create(Base.prototype); // So we get all the `Base` stuff
Derived.prototype.bar = function() {
    console.log("I'm Derived#bar");
};

var d = new Derived();
d.foo(); // "I'm Base#foo"
d.bar(); // "I'm Derived#bar" 

...在ES5之前的环境中,你使用垫片/ polyfill Object.create 。但同样,我不直接这样做(并且不推荐它),我使用帮助脚本,因此它是声明性的和可重复的。

...where in a pre-ES5 environment, you use a shim/polyfill for Object.create. But again, I don't do this directly (and don't recommend it), I use helper scripts so it's declarative and repeatable.

这篇关于anObject.prototype.constructor有什么作用?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆