枚举性如何决定Object.assign拷贝结果的本质差异?
- 内容介绍
- 相关推荐
本文共计572个文字,预计阅读时间需要3分钟。
`Object.assign()` 方法仅复制自身可枚举属性,不包括自身不可枚举属性。这是它的核心规则。泛指性不是访问权限问题,而是决定这个属性是否应该被常规遍历和复制的问题。理解这一点,就能预测 `Object.assign()` 复制什么、遗漏什么。
什么是可枚举属性?
每个对象属性都有一个 enumerable 描述符(布尔值)。为 true 时,该属性会在以下场景中出现:
-
for...in循环 Object.keys()JSON.stringify()- Object.assign()
为 false 时,这些操作都“视而不见”——但你仍能直接通过点号或方括号读写它,比如 obj.hiddenProp 是完全合法的。
Object.assign 明确跳过的两类属性
它只处理“自身 + 可枚举”的属性,其余一律忽略:
-
原型链上的属性:即使可枚举,也不拷贝。例如用
Object.create({ inherited: 1 })创建的对象,inherited不会进目标对象。 -
不可枚举的自有属性:最常见于
Object.defineProperty默认创建的属性。例如:
哪些操作会让属性变成不可枚举?
日常开发中,以下方式默认产生不可枚举属性:
-
Object.defineProperty(obj, key, { value, enumerable: false })(显式设为 false) -
Object.defineProperties(obj, { key: { value } })(省略enumerable时默认 false) - 类中的方法(如
class A { method(){} }),其方法属性默认不可枚举 - 大部分内置对象的内部属性(如
Array.prototype.map在实例上不可枚举)
如何验证一个属性是否可枚举?
用 Object.getOwnPropertyDescriptor 查看描述符:
本文共计572个文字,预计阅读时间需要3分钟。
`Object.assign()` 方法仅复制自身可枚举属性,不包括自身不可枚举属性。这是它的核心规则。泛指性不是访问权限问题,而是决定这个属性是否应该被常规遍历和复制的问题。理解这一点,就能预测 `Object.assign()` 复制什么、遗漏什么。
什么是可枚举属性?
每个对象属性都有一个 enumerable 描述符(布尔值)。为 true 时,该属性会在以下场景中出现:
-
for...in循环 Object.keys()JSON.stringify()- Object.assign()
为 false 时,这些操作都“视而不见”——但你仍能直接通过点号或方括号读写它,比如 obj.hiddenProp 是完全合法的。
Object.assign 明确跳过的两类属性
它只处理“自身 + 可枚举”的属性,其余一律忽略:
-
原型链上的属性:即使可枚举,也不拷贝。例如用
Object.create({ inherited: 1 })创建的对象,inherited不会进目标对象。 -
不可枚举的自有属性:最常见于
Object.defineProperty默认创建的属性。例如:
哪些操作会让属性变成不可枚举?
日常开发中,以下方式默认产生不可枚举属性:
-
Object.defineProperty(obj, key, { value, enumerable: false })(显式设为 false) -
Object.defineProperties(obj, { key: { value } })(省略enumerable时默认 false) - 类中的方法(如
class A { method(){} }),其方法属性默认不可枚举 - 大部分内置对象的内部属性(如
Array.prototype.map在实例上不可枚举)
如何验证一个属性是否可枚举?
用 Object.getOwnPropertyDescriptor 查看描述符:

