可枚举是什么意思?

我被指向 MDN 的 为了. . 在页,它说,“在 Iterates,一个对象的可枚举属性。”

然后我转到 属性页的可枚举性和所有权,它说: “可枚举属性是那些可以由 for 进行迭代的属性。.循环播放”

字典将可枚举定义为可数,但我实在想象不出这意味着什么。我能举个例子吗?

65103 次浏览

可枚举属性是指在 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对象和属性的范围内讨论了这个问题。

还有一个关于 为什么要将属性设置为不可枚举的的堆栈溢出问题。

如果你很难想象“可枚举是什么意思?”为什么不问问自己,成为 数不胜数意味着什么?

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

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 */的位置

这比想象中的无聊多了

所有属性上都有一个名为“可枚举”的属性当它设置为 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']

他们应该直接称之为“无能”

方法是不可枚举的; 或者更确切地说,内置方法是不可枚举的。.在搜索了 数不胜数对 java 脚本的意义之后,它只引用了一个 property 属性。.所有在 ecma3中创建的对象都是可枚举的,并且 ecma5现在可以定义它... ... 就是这样。.: D lol 花了我一点时间去寻找答案; 但我相信它在大卫 · 弗拉纳根的书中有所提及。.所以我猜它的意思是“隐藏”,或者不是“隐藏”在那个方法中没有在 for in 循环中显示,因此是“隐藏”的

我将写一行 数不胜数的定义

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

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

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

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