本文档涵盖了 JavaScript 的对象系统、原型继承机制和类语法。它探讨了对象如何构成 JavaScript 核心支柱之一(原型)的基础,this 关键字如何实现动态上下文绑定,以及 class 语法如何提供一种更具声明性的方式来表达面向对象设计。这是理解 JavaScript 程序中数据和行为如何组织的关键知识。
有关原始类型和类型强制的详细信息,请参阅类型与语法。有关作用域和闭包的更多信息,请参阅作用域与闭包。
JavaScript 的对象机制是一种灵活而强大的容器类型,它允许您存储和组织数据与行为。尽管 JavaScript 中并非所有事物都是对象(与普遍的误解相反),但对象是 JavaScript 三大支柱之一:原型系统的基础。
JavaScript 中的对象系统由几个关键组件组成
this 绑定 - 方法调用的动态上下文来源:objects-classes/ch1.md12-18 objects-classes/ch2.md8-13 objects-classes/ch3.md8-18 objects-classes/ch4.md8-22
JavaScript 中的对象是键/值对的集合,其中键(属性名)通常是字符串,值可以是任何有效的 JavaScript 值。对象可以通过对象字面量语法或通过构造函数创建。
属性可以通过点表示法(object.property)或括号表示法(object["property"])访问。当属性名包含特殊字符或在运行时计算时,需要使用括号表示法。
有关对象基础的更多详细信息,请参阅对象基础。
来源:objects-classes/ch1.md32-50 objects-classes/ch1.md61-75 objects-classes/ch1.md313-326
JavaScript 中的对象遵循一套被称为“元对象协议”(MOP)的规则。该协议定义了属性的行为方式以及对象之间如何交互。
对象上的每个属性都由一个属性描述符描述——一个控制属性行为的元数据对象
属性描述符允许对属性行为进行细粒度控制
value:属性的实际值enumerable:控制属性是否出现在枚举中writable:控制属性的值是否可以更改configurable:控制属性的描述符是否可以修改属性也可以定义为带有 getter 和 setter 的“访问器属性”,而不是简单的值。
JavaScript 对象最重要的特性之一是原型链,在规范中表示为 [[Prototype]]。这种内部链接允许对象将属性访问委托给其他对象
来源:objects-classes/ch2.md14-123 objects-classes/ch2.md268-308
JavaScript 类于 ES6 (2015) 引入,为创建具有共享行为的对象提供了更清晰、更具声明性的语法。虽然最初主要是在现有原型系统之上的语法糖,但类后来演变为一个更强大的功能,具有更多能力。
类可以使用类声明或类表达式来定义
来源:objects-classes/ch3.md66-104
每个类都有一个构造函数方法,当使用 new 关键字创建新实例时会调用该方法。构造函数初始化实例
在类方法中,this 指向当前实例。方法定义在原型对象上,而不是直接在每个实例上,这意味着它们在所有实例之间共享。
来源:objects-classes/ch3.md109-133 objects-classes/ch3.md182-202
this类方法中的 this 关键字指向调用该方法的当前实例
这使得方法可以访问同一实例中的实例属性和其他方法。
来源:objects-classes/ch3.md204-233
类可以直接在类体中声明公共字段,这些字段对应于将在每个实例上创建的属性
公共字段可以有默认值,并且可以使用 this 相互引用。
来源:objects-classes/ch3.md235-274
JavaScript 类通过 extends 关键字支持继承
extends 关键字创建了子类-父类关系,子类从父类继承方法和属性。子类可以覆盖继承的属性和方法,并且可以使用 super 关键字访问父类的实现。
来源:objects-classes/ch3.md374-407
super 进行方法重写子类可以重写其父类的方法,并且仍然可以使用 super 访问父类的实现
当子类提供自己的构造函数时,它必须在使用 this 之前调用 super()
来源:objects-classes/ch3.md422-486 objects-classes/ch3.md489-521
类可以定义静态属性和方法,这些属性和方法直接在类本身上访问,而不是在实例上访问
静态成员被子类继承,并且可以使用子类名称访问。
来源:objects-classes/ch3.md710-765
来源:objects-classes/ch3.md15-18 objects-classes/ch5.md8-22
this 关键字JavaScript 中的 this 关键字为函数调用提供了动态上下文。与许多其他编程语言不同,this 的值不是在函数编写时确定的,而是在其调用时确定的。
this 绑定规则this 的值根据以下四条规则确定,按优先级顺序排列
new 绑定:当函数与 new 一起调用时,this 指向新创建的对象call()、apply() 或 bind() 一起调用时,this 被显式设置this 指向该对象this 指向全局对象;在严格模式下,它是 undefined有关 this 绑定的更多详细信息,请参阅“this”关键字。
来源:objects-classes/ch4.md22-87 objects-classes/ch4.md89-137
虽然类是 JavaScript 中组织代码最常见的方式,但该语言也通过其原型机制支持对象委托。这使得对象可以将行为委托给其他对象,而无需使用类继承。
在这种方法中,对象通过原型链连接,方法从一个对象委托给另一个对象。这创建了一个灵活的组合模型,与经典继承不同。
有关委托模式的更多信息,请参阅委托模式。
来源:objects-classes/ch5.md254-326
JavaScript 提供了多种组织代码和行为的方式
| 方法 | 优点 | 缺点 | 最佳用途 |
|---|---|---|---|
| 对象字面量 | 简单、直接 | 重用受限 | 一次性对象 |
| 工厂函数 | 封装,无需 new | 内存使用(每个实例都有自己的方法) | 隐私,数据闭包 |
| 类 | 熟悉的 OOP 模式,方法共享 | 复杂性,僵化继承结构 | 复杂领域模型,团队熟悉 OOP |
| 委托 | 灵活组合,运行时适应性 | 不那么主流,更抽象 | 动态行为共享,避免深度继承 |
您选择的方法取决于您的具体需求、团队偏好以及项目要求。
来源:objects-classes/ch3.md20-64 objects-classes/ch5.md26-45
JavaScript 的对象和类系统为组织代码提供了灵活的基础
this 关键字允许动态上下文绑定理解这些概念对于高效的 JavaScript 编程至关重要,因为它们构成了该语言的三大支柱之一。
来源:objects-classes/ch1.md12-18 objects-classes/ch3.md8-18 objects-classes/ch4.md8-22