。我通常会在将对象分配给函数原型时看到JQuery源代码或其他javascript框架源代码,他们通常会这样做:
function A(){}
A.prototype = {
constructor: A,
// ....
}
我真的很困惑。我的意思是为什么必须这样做?
答案 0 :(得分:2)
在JavaScript中,所有正常创建的函数都具有prototype
属性,该属性最初是由JavaScript引擎创建的对象,其中包含一个属性constructor
,该属性引用该函数。
function A() {
}
......我们最初知道A.prototype.constructor === A
。这也意味着通过new A
创建的对象将继承constructor
,因此:
var o = new A();
console.log(o.constructor === A); // true
但是,如果你用其他东西替换 prototype
属性上的对象,就像你的代码片段一样,那么新东西的constructor
属性(它继承了)是指向错误的功能,除非你修复它:
function A() {
}
A.prototype = {}; // Replace the object
var o = new A();
console.log(o.constructor === A); // false
console.log(o.constructor === Object); // true
糟糕。这就是为什么您引用的代码段会在constructor
分配的对象上设置A.prototype
。
但是constructor
属性的重点是什么?实际上,JavaScript规范中没有任何内容使用该属性;唯一提到它与上面有关,确保prototype
属性上的初始对象有constructor
引用回函数。
但是一些代码(包括一些库)可能会假设constructor
被“正确”设置(例如,JavaScript引擎默认设置的方式),并且可能会尝试使用它来弄清楚什么是对象“是”(虽然通常很少有理由这样做;在极少数情况下,当你真正关心时,instanceof
通常是更好的检查方式,因为它允许派生对象)。或者他们可能会尝试在克隆操作中使用它,尽管从ES5开始有更好的方法。
在任何情况下,由于存在(稀有)代码,可能依赖于JavaScript引擎设置的constructor
属性,行为良好的代码完全替换prototype
属性设置constructor
的方式与JavaScript引擎相同,以防万一。
在实践中,人们在更换prototype
属性上的对象时忽略该步骤非常常见,因此在新代码中依赖constructor
不是最佳实践。但是,为了以防万一,确保正确设置constructor
可能仍然存在。