你不知道的 JavaScript 系列上, 51 - 假构造函数

function Foo() {
  // ...
}
var a = new Foo();

是什么让我们认为 Foo 是一个类,Foo() 是构造函数调用。其中一个原因是我们看到了关键字 new。

除了令人迷惑的构造函数语义外,Foo.prototype 还有另一个绝招

function Foo() {
  // ...
}
Foo.prototype.constructor === Foo; // true
var a = new Foo();
a.constructor === Foo; // true

Foo.prototype 默认有一个公有并且不可枚举的属性 constructor,这个属性引用的是对象关联的函数,本例是 Foo。此外,a 也有一个 constructor 属性,指向创建这个对象的函数。

实际上 a 本身并没有 constructor 属性。而且,虽然 a.constructor 确实指向 Foo 函数,但是这个属性并不表示 a 是由 Foo 构造。

类名首字母要大写,所以名字写作 Foo 而不是 foo,如果不大写,许多 JS 开发者都会责怪你,amazing。我们竟然这么努力地维护这个假类。

很容易认为 Foo 是一个构造函数,因为我们使用 new 来调用他并且看到他构造了一个对象。实际上,Foo 和程序中的其他函数没有任何区别。但是使用 new 调用时,它就会构造一个对象并赋值给 a。但是 Foo 本身并不是一个构造函数

换句话说,在 JS 中对于构造函数最准确的解释是,所有带 new 的函数调用。函数不是构造函数,但是当且仅当使用 new 时,函数调用会变成构造函数调用