本文档解释了 JavaScript 的对象值在类型系统中是如何工作的。对象是 JavaScript 的基本值类型之一,与原始值不同,理解它们的行为对于有效的 JavaScript 编程至关重要。有关原始值(如字符串、数字和布尔值)的信息,请参阅原始值。
JavaScript 中的对象值具有几个关键特征,使其区别于原始值
来源:types-grammar/ch3.md14-26 types-grammar/ch1.md8-26
对象在创建后可以被修改,而原始值是不可变的。这是它们行为方式的一个根本区别
来源:types-grammar/ch2.md14-46 types-grammar/ch3.md8-14
JavaScript 的对象值类型包含几种子类型,每种都有其专门的行为
| 对象类型 | 描述 | 使用示例 |
|---|---|---|
| 普通对象 | 基本的键值集合 | {name: "Kyle", age: 39} |
| 基础对象 | 包装原始值 | new String("hello") |
| 数组 | 数字索引集合 | [1, 2, 3] |
| 函数 | 可调用对象 | function() {} |
| 正则表达式 | 模式匹配 | /[a-z]+/g |
| 其他内置对象 | Date, Error, Map 等。 | new Date() |
来源:types-grammar/ch3.md14-26 types-grammar/toc.md26-35
普通对象(有时称为“POJOs”——Plain Old JavaScript Objects)是最常见的对象类型。它们充当命名属性的集合,每个属性保存任何类型的值。
默认情况下,普通对象与[[Prototype]] 链接到Object.prototype,使它们能够访问内置方法,如toString()、valueOf()等。
与按值复制的原始值不同,对象是按引用赋值的
当你将一个对象赋值给一个变量或将其传递给一个函数时,你操作的是该对象的引用,而不是一个新副本。这导致了 JavaScript 中一个非常常见的陷阱:多个变量可以指向同一个对象,通过任何一个引用进行的修改都会影响底层对象。
来源:types-grammar/ch2.md103-130
JavaScript 为原始类型提供了对象包装构造函数
new String() - 包装字符串原始值new Number() - 包装数字原始值new Boolean() - 包装布尔值原始值由于 JavaScript 会自动执行自动装箱,这些很少需要直接使用。
当在原始值上访问属性或方法时,JavaScript 会自动将该原始值包装到其对应的对象类型中
这发生在后台,并允许原始值表现得好像它们具有属性和方法一样
来源:types-grammar/ch3.md68-146 types-grammar/ch1.md65-91
数组是经过优化的、用于数字索引值集合的专用对象
数组与Array.prototype 具有[[Prototype]] 链接,这使它们能够访问各种数组特有的方法
push()、pop()、sort() 等。map()、filter()、concat() 等。indexOf()、includes() 等。尽管有特殊处理,数组本质上仍然是对象,甚至可以向其添加命名属性(尽管不推荐这样做)。
来源:types-grammar/ch3.md158-189
JavaScript 中的函数是专门的对象,可以被调用或执行。与许多其他语言不同,JavaScript 函数是第一类值,可以被
作为对象,函数具有特殊属性,如name、length(声明的参数数量),以及call() 和 apply() 等方法。
来源:types-grammar/ch3.md194-196 types-grammar/toc.md33
与具有相当直接的强制类型转换规则的原始值不同,对象具有特殊的强制类型转换行为
toString() 方法,如果需要则回退到valueOf()valueOf() 方法,如果需要则回退到toString()true(所有对象都是“真值”)此行为在ToPrimitive() 抽象操作中得到正式定义,该操作在强制类型转换期间被调用。
来源:types-grammar/ch4.md87-105 types-grammar/ch4.md151-166
JavaScript 有一个提案(撰写时处于第二阶段),关于记录(Records)和元组(Tuples)——对象和数组的不可变版本,它们的行为更像原始值
#{name: "Kyle"}) - 对象的不可变替代品#[1, 2, 3]) - 数组的不可变替代品这些将是原始值(不是对象),使它们不可变,并允许它们通过值而不是引用进行比较。
来源:types-grammar/ch3.md198-206
| 操作 | 描述 | 示例 |
|---|---|---|
| 属性访问 | 获取命名属性的值 | obj.prop 或 obj["prop"] |
| 属性赋值 | 设置命名属性的值 | obj.prop = value |
| 属性存在性检查 | 测试属性是否存在 | "prop" in obj 或 obj.hasOwnProperty("prop") |
| 属性枚举 | 列出属性 | Object.keys(obj) 或 for..in 循环 |
| 属性删除 | 删除属性 | delete obj.prop |
| 对象比较 | 按引用比较 | obj1 === obj2(仅当引用相同时为 true) |
| 对象复制 | 创建浅拷贝 | Object.assign({}, obj) 或 {...obj} |
JavaScript 中对象值的这些基本方面为在语言中组织代码、表示数据和构建抽象提供了基础。