可枚举的属性是可以包含在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'
但是,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
如果通过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中的Non-enumerable属性,但显示了被枚举的对象。属性可以是可写,可配置或可枚举的,也可以是不可写的。John Resig在ECMAScript 5对象和属性的范围内对此进行了讨论。
而且,还有一个堆栈溢出问题,关于您为什么要使属性不可枚举。
这比应该可视化的东西更无聊。
实际上,所有属性上都有一个称为“可枚举”的属性。如果将其设置为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..in
否则Object.keys
它将完全是秘密的:
console.log(Object.keys(car)); //prints ['make', 'model', 'year', 'condition', 'mileage']
他们应该将其称为“ forInAble”。
如果您难以想象“可枚举意味着什么?” 为什么不问自己,无数意味着什么呢?
我这样想,存在一个不可数的属性,但部分被隐藏了;意思是无数是怪异的。现在您可以想象剩下的可枚举了-自从发现对象以来我们曾经遇到的更自然的属性。考虑
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 */
我将写一个ENUMERABLE的行定义
Enumerable
:指定是否可以在for / in循环中返回该属性。
var obj = {};
Object.defineProperties(obj, {
set1: {enumerable: true},
set2: {enumerable: false},
});
Object.keys(obj); // ["set1"]
Object.getOwnPropertyNames(obj); // ["set1", "set2"]
方法是无法枚举的;在搜索了 Java脚本的可枚举含义之后,就没有了。它只是指向属性属性。.在ecma3中创建的所有对象都是可枚举的,并且ecma5现在可以定义它了。但是我相信它在David Flanagan的书中已经讨论过。.因此,我认为它的意思是“隐藏”,而不是“隐藏”,因为for循环中未显示这些方法,因此被“隐藏”
考虑枚举数据类型,只是对应于不同数字的对象的结构。将某事物声明为可枚举就是声明它对应于特定数字,从而允许它在字典中被赋予代表对象的可数组成部分的位置。简单地说,使对象可枚举与告诉编译器相同:“嘿,这个属性很重要,当我检查该对象上的数据时,我希望看到它。”
对象继承的内置方法不是可枚举的,但是代码中添加到对象的属性是可枚举的,除非明确说明
文章标签:enumerable , javascript
版权声明:本文为原创文章,版权归 javascript 所有,欢迎分享本文,转载请保留出处!
评论已关闭!