可枚举是什么意思?

2022-08-30 02:05:18

我被引导到MDN的..在页面中,当它说,“为..中迭代对象的可枚举属性。

然后我转到“属性的可枚举性和所有权”页面,其中说“可枚举属性是那些可以通过 for.在循环中。

字典将可枚举定义为可数,但我无法真正想象这意味着什么。我能举个例子说明一些东西是可枚举的吗?


答案 1

可枚举属性是可以在循环(或类似的属性迭代,如 )中包含和访问的属性。for..inObject.keys()

如果某个属性未标识为可枚举,则循环将忽略该属性位于对象内。

var obj = { key: 'val' };

console.log('toString' in obj); // true
console.log(typeof obj.toString); // "function"

for (var key in obj)
    console.log(key); // "key"

属性通过其自己的 [[可枚举]] 属性标识为可枚举或不可枚举。您可以将其作为属性描述符的一部分进行查看:

var descriptor = Object.getOwnPropertyDescriptor({ bar: 1 }, 'bar');

console.log(descriptor.enumerable); // true
console.log(descriptor.value);      // 1

console.log(descriptor);
// { value: 1, writable: true, enumerable: true, configurable: true }

然后,循环循环访问对象的属性名称。for..in

var foo = { bar: 1, baz: 2};

for (var prop in foo)
    console.log(prop); // outputs 'bar' and 'baz'

但是,仅评估其语句 ( 在本例中 ) 对于属性为 .console.log(prop);[[Enumerable]]true

之所以存在此条件,是因为对象具有更多属性,尤其是来自继承的属性

console.log(Object.getOwnPropertyNames(Object.prototype));
// ["constructor", "toString", "toLocaleString", "valueOf", "hasOwnProperty", "isPrototypeOf", "propertyIsEnumerable", /* etc. */]

以下每个属性仍存在于对象上

console.log('constructor' in foo); // true
console.log('toString' in foo);    // true
// etc.

但是,它们被循环跳过,因为它们不可枚举。for..in

var descriptor = Object.getOwnPropertyDescriptor(Object.prototype, 'constructor');

console.log(descriptor.enumerable); // false

答案 2

如果通过或类似方式创建对象,则所有属性都是可枚举的。因此,更容易问的问题是,什么是不可枚举的?某些对象具有一些不可枚举的属性,例如,如果您调用(在 [] 上返回所有属性的数组,无论是否可枚举),它将返回 ,其中包括数组的不可枚举属性 'length'。myObj = {foo: 'bar'}Object.getOwnPropertyNames([])['length']

您可以通过调用以下命令来创建自己的不可枚举属性:Object.defineProperty

var person = { age: 18 };
Object.defineProperty(person, 'name', { value: 'Joshua', enumerable: false });

person.name; // 'Joshua'
for (prop in person) {
  console.log(prop);
}; // 'age'

此示例大量借鉴了 JavaScript 中的不可枚举属性,但显示了一个正在枚举的对象。属性可以是可写的,也可以不是可写的、可配置的或可枚举的。John Resig 在 ECMAScript 5 Objects and Properties 的范围内讨论了这一点。

而且,有一个 Stack Overflow 问题,关于为什么你想要使属性不可枚举