Javascript “可枚举”是什么意思?

Javascript “可枚举”是什么意思?,javascript,enumerable,Javascript,Enumerable,当MDN说“for..in迭代对象的可枚举属性”时,我被引导到MDN 然后我去了,它说“可枚举属性是那些可以被for..in循环迭代的属性。” 字典将可枚举定义为可数,但我无法真正想象这意味着什么。我可以举出一个可枚举的例子吗?可枚举属性是一个可以包含在for..in循环(或类似的属性迭代,如Object.keys())中并在循环中访问的属性 如果属性未标识为可枚举,则循环将忽略它位于对象内 var obj = { key: 'val' }; console.log('toString' in

当MDN说“for..in迭代对象的可枚举属性”时,我被引导到MDN

然后我去了,它说“可枚举属性是那些可以被for..in循环迭代的属性。”


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

可枚举属性是一个可以包含在
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"

属性由其自身标识为可枚举或不可枚举。您可以将其视为以下内容的一部分:

一个
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
的属性

此条件之所以存在,是因为对象,尤其是:

这些财产中的每一项仍然:

但是,它们被
循环中的..跳过,因为它们不可枚举

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

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

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

您可以通过调用
对象来创建自己的不可枚举属性。defineProperty

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

person.name; // 'Joshua'
for (prop in person) {
  console.log(prop);
}; // 'age'
此示例大量借用了,但显示了正在枚举的对象。属性可以是或不是可写、可配置或可枚举的。John Resig在本文的范围内对此进行了讨论


还有一个关于堆栈溢出的问题。

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

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

var o = {};
o['foo'] =  0;                               // enumerable, normal
Object.defineProperty(o, 'bar', {value: 1}); // nonenumerable, weird
现在在一个关于..的
中,把它想象成伪代码

在JavaScript中键入的循环体代替了
/*which*/

的地方,这比应该可视化的东西要无聊得多

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

对象上有很多属性将“enumerable”设置为false,比如“valueOf”和“hasOwnProperty”,因为假定您不希望JavaScript引擎迭代这些属性

您可以使用
对象创建自己的不可枚举属性。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..in
Object.keys
访问它,它将保持完全保密:

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

他们应该称之为“forInAble”。

方法是不可枚举的;或者更确切地说,内置方法不是。。搜索可枚举对java脚本意味着什么之后;它只是指一个属性。。ecma3中所有创建的对象都是可枚举的,ecma5 u现在可以定义它了……就是这样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"]

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

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

Hm,包括上行投票和下行投票。当然,如果这个答案有什么值得否决的地方,请在这里添加评论;o['foo']=0;//可枚举,普通对象。定义属性(o,'bar',{value:1});//不可数,奇怪为什么要显式添加可枚举:false?@Patrick,我在这里包含它的一部分,以便从示例中可以清楚地看出它是一个选项,但取决于您的受众,显式可能是一个可靠的决定,以便阅读您的代码的任何人都能清楚地看到它。@carpeliam感谢您的简短和非常清晰的解释,我无法得到接受的答案,直到我检查了你的答案:DSo构造函数属性是不可枚举的,因为它不会出现在for..in循环中。虽然属性(如bar或baz)的名称是可枚举的,因为您可以从对象中对每个属性进行console.log?这并不完全正确:
,但它们是
  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'
console.log(Object.keys(car)); //prints ['make', 'model', 'year', 'condition', 'mileage']
var obj = {};
Object.defineProperties(obj, {
    set1: {enumerable: true},
    set2: {enumerable: false},
});
Object.keys(obj); // ["set1"]
Object.getOwnPropertyNames(obj); // ["set1", "set2"]