枚举是什么意思

What does enumerable mean?

本文关键字:意思 是什么 枚举      更新时间:2023-09-26

我被引导到MDN。。在页面中,当它说"for…in迭代对象的可枚举属性。"

然后我转到属性的可枚举性和所有权页面,上面写着"可枚举属性是那些可以通过for.in循环迭代的属性。"

字典把enumerable定义为可计数,但我真的无法想象这意味着什么。我能举一个可枚举的例子吗?

可枚举属性是指可以在for..in循环(或类似的属性迭代,如Object.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"

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

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'

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

这个条件之所以存在,是因为对象有更多的属性,尤其是继承的属性:

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

如果通过myObj = {foo: 'bar'}或其附近的东西创建对象,则所有属性都是可枚举的。所以更容易问的问题是,什么是不可枚举的?某些对象具有一些不可枚举的属性,例如,如果调用Object.getOwnPropertyNames([])(它在[]上返回所有属性的数组,无论是否可枚举),它将返回['length'],其中包括数组的不可枚举属性"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对象和属性的范围中对此进行了讨论。

还有一个Stack Overflow问题,关于为什么要使属性不可枚举。

它比应该可视化的东西要无聊得多

所有属性上都有一个名为"enumerable"的属性。当它设置为false时,for..in方法将跳过该属性,假装它不存在。

对象上有很多属性的"enumerable"设置为false,比如"valueOf"answers"hasOwnProperty",因为据推测,您不希望JavaScript引擎对这些属性进行迭代。

您可以使用Object.defineProperty方法创建自己的不可枚举属性:

  var car = {
    make: 'Honda',
    model: 'Civic',
    year: '2008',
    condition: 'bad',
    mileage: 36000
  };
  Object.defineProperty(car, 'mySecretAboutTheCar', {
    value: 'cat pee in back seat',
    enumerable: false
  });

现在,这辆车甚至有一个秘密被掩盖了。当然,他们仍然可以直接访问该房产并得到答案:

console.log(car.mySecretAboutTheCar); // prints 'cat pee in back seat'

但是,他们必须首先知道该属性存在,因为如果他们试图通过for..inObject.keys访问它,它将保持完全机密:

console.log(Object.keys(car)); //prints ['make', 'model', 'year', 'condition', 'mileage']

他们应该把它称为"forInAble"。

我将写一行ENUMERABLE的定义

Enumerable:指定是否可以在for/in循环中返回属性。

var obj = {};
Object.defineProperties(obj, {
    set1: {enumerable: true},
    set2: {enumerable: false},
});
Object.keys(obj); // ["set1"]
Object.getOwnPropertyNames(obj); // ["set1", "set2"]

如果你很难想象"可枚举意味着什么?"为什么不问问自己,不可枚举是什么?

我认为它有点像这样,一个不可计数属性存在,但被部分隐藏;这意味着不可计数就是奇怪的一个。现在,您可以将枚举想象为剩下的东西——自从我们发现对象以来,我们已经习惯于遇到更自然的属性。考虑

var o = {};
o['foo'] =  0;                               // enumerable, normal
Object.defineProperty(o, 'bar', {value: 1}); // nonenumerable, weird

现在在for..in中,想象它像伪代码

for property in o:
    if not property enumerable continue // skip non-enumerable, "bar"
    else do /* whatever */              // act upon enumerable, "foo"

其中,您在JavaScript中键入的循环主体位于/* whatever */

对象继承的内置方法不是可枚举,但代码添加到对象的属性是可枚举的,除非明确声明

想想枚举数据类型,它只是对应于不同数字的对象的结构。将某个对象声明为可枚举对象就是声明它对应于一个特定的数字,允许它在表示对象的可计数组件的字典中占有一席之地。简单地说,使对象可枚举与告诉编译器"嘿,这个属性很重要,我想在检查这个对象的数据时看到它。"

方法是不可枚举的;或者更确切地说,内置方法不是。。tho在搜索enumerable对java脚本意味着什么之后;它只是指一个属性。。ecma3中所有创建的对象都是可枚举的,ecma5u现在可以定义它了……就这样……:我花了一点时间才找到答案;但我相信大卫·弗拉纳根的书中谈到了这一点。。所以我想它的意思是"隐藏的",或者说不是"隐藏",因为方法没有显示在for in循环中,因此是"隐藏"的