可枚举的意思是什么?

时间:2013-07-27 02:38:24

标签: javascript enumerable

我被指示MDN的for..in page,当它说,“for..in迭代一个对象的可枚举属性。”

然后我去了Enumerability and ownership of properties page,它说“可枚举的属性是那些可以通过for..in循环迭代的属性。”

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

8 个答案:

答案 0 :(得分:123)

可枚举属性是可以在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]] attribute标识为可枚举或不可枚举。您可以将其视为property's descriptor

的一部分
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

此条件已到位,因为对象have many more properties,尤其是from inheritance

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

这些属性中的每一个仍为exists on the object

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

答案 1 :(得分:42)

如果您通过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'

此示例大量借用Non-enumerable properties in JavaScript,但显示了一个被枚举的对象。属性可以是可写的,也可以是可配置的,也可以是可枚举的。 John Resig在ECMAScript 5 Objects and Properties的范围内对此进行了讨论。

并且,有一个关于why you'd ever want to make properties non-enumerable的Stack Overflow问题。

答案 2 :(得分:30)

它比应该可视化的东西更无聊。

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

对象中有很多属性具有"可枚举的"设置为false,例如" valueOf"和" 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。"

答案 3 :(得分:9)

如果您难以想象“可枚举的意义是什么?”为什么不问自己,不可数是什么意思?

我认为有点像这样, 无数 属性存在但部分隐藏;意味着不可数是奇怪的。现在你可以想象剩下的东西 - 自从我们发现 Objects 以来我们习惯遇到的更自然的属性。考虑

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 */

的位置

答案 4 :(得分:5)

我会写一行 ENUMERABLE

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

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

答案 5 :(得分:0)

方法不可枚举;或者更确切地说内置方法不是..搜索枚举对java脚本意味着什么;它只是引用了一个属性属性。所有在ecma3中创建的对象都是可枚举的,而ecma5你现在可以定义它......就是它......:D lol带我去找一些答案;但是我相信它在David Flanagan的书中谈过..所以我猜它意味着“隐藏”,或者说“隐藏”在那个方法中没有显示在for循环中,因而是“隐藏”

答案 6 :(得分:0)

考虑枚举数据类型,只是对应于不同数字的对象的结构。将某事物声明为可枚举就是声明该事物对应于特定数字,从而允许它在字典中被赋予代表对象的可数组成部分的位置。简单地说,使对象可枚举与告诉编译器相同:“嘿,这个属性很重要,当我检查该对象上的数据时,我希望看到它。”

答案 7 :(得分:0)

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