Object.assign只拷贝自身可枚举属性,跳过原型链属性和不可枚举的自有属性;可枚举性由enumerable描述符控制,影响for...in、Object.keys()、JSON.stringify()和Object.assign等操作。

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 查看描述符:

















