anObject.prototype.constructor 是做什么的
What does anObject.prototype.constructor do?
假设我们有这个构造函数:
var Foo = function(){
this.x = "y";
}
Foo
和Foo.prototype.constructor
计算相同的函数,但Foo.prototype.constructor = function(){this.x="z"}
似乎并没有改变new Foo()
的结果。 但是,它确实会改变结果
var i = new Foo();
i.constructor; // evals to function (){this.x = "z"}
这是怎么回事? 我不打算将其用于任何事情,我只是对语言感到好奇。
函数的 prototype
属性的 constructor
属性旨在指向函数,以便您可以询问对象是什么构造了它。它是在创建函数对象时自动设置的(请参阅规范的第 13.2 节 [或此处获取更新版本]。如您所见,如果您愿意,可以覆盖Foo.prototype
上的 constructor
属性以更改它,但默认情况下这就是它的用途。多年来,JavaScript 规范只说 constructor
属性将存在并具有给定的默认值(function Foo() { }
意味着默认情况下,Foo.prototype.constructor
Foo
)。但是从 ES2015 开始,情况发生了变化,规范中的各种操作现在实际上使用 constructor
属性,例如 这里、这里、这里和这里。
(请注意,以下内容是在添加ES2015的class
功能之前编写的。以下是您在 ES5 及更早版本中执行此操作的方式。在 ES2015+ 中,如果您正在执行构造函数和继承层次结构,则没有充分的理由执行以下操作;只需使用class
.[如果你不使用构造函数来构建继承层次结构——你不必这样做,还有其他方法可以在 JavaScript 中做到这一点——你就不会做以下操作或使用class
。
你可以覆盖它有一个很好的理由,这与继承有关。假设你想要一个创建基对象的Base
构造函数,以及一个创建具有Base
功能以及Derived
添加/修改的派生对象的Derived
构造函数。您看到完成(缺少辅助脚本)的通常(尽管在我看来并不理想)方式是:
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
.因此,能够解决这个问题很重要:
...
Derived.prototype = new Base(); // So we get all the `Base` stuff
Object.defineProperty(Derived.prototype, "constructor", { // Fix up
value: Derived,
writable: true,
configurable: true
});
...
(旁注:所有这些管道 - 以及围绕超级调用的复杂性 - 是ES2015+具有class
语法的原因。
请注意,上述内容并不是设置继承层次结构的理想方法。这是你通常看到的,但正如我上面所说,并不理想。只是为了完整起见,在仅限于 ES5 语法的环境中,这更好:
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
Object.defineProperty(Derived.prototype, "constructor", {
value: Derived,
writable: true,
configurable: true
});
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 之前的环境中,您使用填充程序/填充填充码进行Object.create
。但同样,我不直接这样做(也不推荐它),我使用帮助程序脚本,所以它是声明性的和可重复的。
.prototype.constructor
只是一个辅助属性,因此创建的对象可以轻松地使用 this.constructor
引用构造函数,或者像您的情况一样i.constructor
。
任意设置为其他内容没有任何影响,除了对期望获取对象的构造函数的代码obj.constructor
:
if( obj.constructor === Foo ) {
//It's a Foo
}
所以就这样是一个很好的约定。
es5shim 依靠.constructor.prototype
来填充Object.getPrototypeOf
- JavaScript prototype.constructor 有什么用
- Array.prototype.reduce的实际用途是什么
- Prototype.js 1.7:将collect与显式函数一起使用会返回与内联函数不同的结果,原因是什么
- 在 Function.prototype.method 中返回它有什么作用
- 常规推送和 Array.prototype.push.apply 有什么区别?
- anObject.prototype.constructor 是做什么的
- Function.prototype.toMethod() 是做什么的
- Array.prototype.some() 是否返回文字?如果是这样,这段代码是什么意思
- Javascript中的Array.prototype.reverse和Array.reverse有什么区别
- Array.prototype.find,什么'它的规格是什么
- this.method与prototype.method有什么区别
- 在 Array.prototype 中传递“for each”循环的参数的语法是什么?
- prototype.constructor的作用是什么
- Array.prototype.join.call 在后台对字符串做什么
- 什么可以阻止Array.prototype.filter()在控制台中运行良好的防油精脚本中运行
- 在Javascript中使用Prototype的优势是什么
- put method into function()和prototype在js中的区别是什么?
- this.constructor.prototype.constructor.apply在js中是什么意思?
- 扩展Object.prototype的缺陷是什么?
- _.extend(Something)和_.extend(Something)之间的区别是什么?prototype, s