为什么javascript函数原型需要修复构造函数?

时间:2015-02-24 10:08:48

标签: javascript jquery constructor

例如,

。我通常会在将对象分配给函数原型时看到JQuery源代码或其他javascript框架源代码,他们通常会这样做:

function A(){}
A.prototype = {
    constructor: A,
    // ....
}

我真的很困惑。我的意思是为什么必须这样做?

1 个答案:

答案 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可能仍然存在。