枚举性如何决定Object.assign拷贝结果的本质差异?

2026-05-07 02:041阅读0评论SEO基础
  • 内容介绍
  • 相关推荐

本文共计572个文字,预计阅读时间需要3分钟。

枚举性如何决定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 默认创建的属性。例如:
const src = {}; Object.defineProperty(src, 'secret', { value: 'x', enumerable: false }); Object.assign({}, src); // → {}(空对象,secret 被跳过)

哪些操作会让属性变成不可枚举?

日常开发中,以下方式默认产生不可枚举属性:

  • Object.defineProperty(obj, key, { value, enumerable: false })(显式设为 false)
  • Object.defineProperties(obj, { key: { value } })(省略 enumerable 时默认 false)
  • 类中的方法(如 class A { method(){} }),其方法属性默认不可枚举
  • 大部分内置对象的内部属性(如 Array.prototype.map 在实例上不可枚举)

如何验证一个属性是否可枚举?

Object.getOwnPropertyDescriptor 查看描述符:

const obj = {}; Object.defineProperty(obj, 'a', { value: 1 }); Object.defineProperty(obj, 'b', { value: 2, enumerable: true }); console.log(Object.getOwnPropertyDescriptor(obj, 'a').enumerable); // false console.log(Object.getOwnPropertyDescriptor(obj, 'b').enumerable); // true

本文共计572个文字,预计阅读时间需要3分钟。

枚举性如何决定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 默认创建的属性。例如:
const src = {}; Object.defineProperty(src, 'secret', { value: 'x', enumerable: false }); Object.assign({}, src); // → {}(空对象,secret 被跳过)

哪些操作会让属性变成不可枚举?

日常开发中,以下方式默认产生不可枚举属性:

  • Object.defineProperty(obj, key, { value, enumerable: false })(显式设为 false)
  • Object.defineProperties(obj, { key: { value } })(省略 enumerable 时默认 false)
  • 类中的方法(如 class A { method(){} }),其方法属性默认不可枚举
  • 大部分内置对象的内部属性(如 Array.prototype.map 在实例上不可枚举)

如何验证一个属性是否可枚举?

Object.getOwnPropertyDescriptor 查看描述符:

const obj = {}; Object.defineProperty(obj, 'a', { value: 1 }); Object.defineProperty(obj, 'b', { value: 2, enumerable: true }); console.log(Object.getOwnPropertyDescriptor(obj, 'a').enumerable); // false console.log(Object.getOwnPropertyDescriptor(obj, 'b').enumerable); // true