构造函数

new 操作符通过构造函数和原型创建一个新的对象。

构造函数是一个与对象名称匹配的函数,当通过 new 操作符调用时,this 关键字会被赋值给新创建的对象实例。然后,构造函数可以根据需要分配初始变量。

function CoinObject() {
  this.value = 0;
}
var slug = new CoinObject();  // 创建一个“slug”对象——没有值的硬币 (slug.value = 0)

构造函数可以接受参数;然而,不可能通过定义多个具有不同参数数量的函数来实现构造函数的重载。

new 语句是创建新 JavaScript 对象的最常见方法,但有些 JavaScript 程序员有时会使用其他技术[1][2])。


原型

对象的原型是自动创建的字段和方法的集合。它本身不能操作,而是依赖于现有的构造函数。

当对象被创建时,原型中初始化的字段会被复制到新创建的对象中。

function CoinObject() {
  this.value = 0;
}
CoinObject.prototype.diameter = 1;
slug = new CoinObject();  // 创建一个没有值的硬币 (slug.value = 0),直径为 1 (slug.diameter = 1)

由于对象的原型本身也是对象,因此可以利用原型来实现继承。


动态扩展对象

JavaScript 中的对象是完全动态的,如果对象中不存在某个字段,可以立即创建该字段。例如,如果在硬币的例子中,后来发现需要跟踪硬币的厚度,可以简单地将新的字段添加到原型中。

更改对象的原型会使该对象的现有实例也能访问到这些变化。

当一个新对象为某个属性分配了值时,该属性会优先于原型中的同名属性。如果你删除新对象中的这个属性,继承链会回到父对象中该属性的值。

以下是一个示例,使用 Animal 构造函数创建了一个对象,一个名叫 Spot 的狗。在创建后,给构造函数添加了 gender 属性。这个 gender 属性也可以通过对象 Spot 访问。

gender 属性可以被更新,如果从 dog 对象中删除 gender 属性,它会从祖先对象 Animal 构造函数中检索到该属性。

function Animal (type, name) {
  this.type = type || 'No type';
  this.name = name || 'No name';
}
var dog = new Animal('dog', 'Spot');

// 给 Animal 对象添加 gender 属性
Animal.prototype.gender = 'unspecified';
// dog.gender 是 'unspecified'

dog.gender = 'male';
// dog.gender 是 'male'

delete(dog.gender);
// dog.gender 重新变为 'unspecified'

参考文献

  • Greg Tatum. "Killing JavaScript's this". 例子展示了 JavaScript 支持许多传统面向对象编程的替代方案。部分章节“典型的面向对象 JavaScript”。
  • Douglas Crockford. "Crockford on JavaScript -- Act III: Function the Ultimate" pdf 和视频。描述了几种不同的 JavaScript 对象构造函数实现方式。
Last modified: Monday, 13 January 2025, 3:06 PM