enumerable 属性忽略规则

四种会忽略 enumerable 为 false 属性的操作

问题

JavaScript 中有哪四个操作会忽略 enumerablefalse 的属性?

解答

enumerable 是属性描述符的一个特性,决定属性是否可枚举。以下四个操作会忽略不可枚举的属性:

1. for…in 循环

const obj = {};

Object.defineProperty(obj, 'a', {
  value: 1,
  enumerable: true
});

Object.defineProperty(obj, 'b', {
  value: 2,
  enumerable: false
});

for (let key in obj) {
  console.log(key); // 只输出 'a'
}

2. Object.keys()

const obj = {};

Object.defineProperty(obj, 'a', {
  value: 1,
  enumerable: true
});

Object.defineProperty(obj, 'b', {
  value: 2,
  enumerable: false
});

console.log(Object.keys(obj)); // ['a']

3. JSON.stringify()

const obj = {};

Object.defineProperty(obj, 'a', {
  value: 1,
  enumerable: true
});

Object.defineProperty(obj, 'b', {
  value: 2,
  enumerable: false
});

console.log(JSON.stringify(obj)); // '{"a":1}'

4. Object.assign()

const obj = {};

Object.defineProperty(obj, 'a', {
  value: 1,
  enumerable: true
});

Object.defineProperty(obj, 'b', {
  value: 2,
  enumerable: false
});

const newObj = Object.assign({}, obj);
console.log(newObj); // { a: 1 }

不受影响的操作

const obj = {};

Object.defineProperty(obj, 'zzinb', {
  value: 'secret',
  enumerable: false
});

// 这些操作可以获取不可枚举属性
console.log(Object.getOwnPropertyNames(obj)); // ['zzinb']
console.log(Object.getOwnPropertyDescriptors(obj)); // { hidden: {...} }
console.log(Reflect.ownKeys(obj)); // ['zzinb']
console.log(obj.hidden); // 'secret'

关键点

  • for...in 只遍历可枚举属性(包括原型链上的)
  • Object.keys() 只返回自身可枚举属性
  • JSON.stringify() 只序列化可枚举属性
  • Object.assign() 只复制源对象的可枚举属性
  • Object.getOwnPropertyNames()Reflect.ownKeys() 可获取不可枚举属性