你可以在javascript中创建属性可枚举但不可迭代吗? [英] Can you make properties enumerable but not iterable in javascript?
问题描述
我只是想知道是否有一种方法来使对象属性可枚举,就像在循环中的
一样,但不显示在
中的循环
类似于
Object.defineProperty({},'prop',{
可枚举:true,
iterable:false
}
有没有计划实现这样的功能?或者循环的使用枚举属性
我在Mozilla开发网络(MDN)上做了一些挖掘。
证明对象有一个 obj.propertyIsEnumerable(prop)
方法来检查属性是否是可枚举的。从MDN中给出的示例中,通过原型链继承的属性不是可枚举的,因此该方法为这些属性返回false。 / p>
非枚举属性的一个例子是构造函数和数组的属性 length
。
对于问题的可迭代部分,我将引用MDN:ECMAScript 6中的可迭代是一个接口(或者换句话说,一个协议),而不是像Array或地图。
也就是说,对象需要实现这个接口,使其属性可以迭代。这是内置的iterable,如String,Array,Map,Set,WeakSet和Generator对象的情况。
以下代码说明了这一点:
var aString =hello
typeof aString [Symbol.iterator] //function
aString [Symbol.iterator] ()+//[object String Iterator]
[... aString] // [h,e,l,l,o]
当然,您可以定义自己的迭代器实现。
回到这个问题,附加到对象或其原型的属性(直接意味着不通过继承)将在中的
中显示为
循环中的枚举。对于迭代,您需要一个实现,前面提到的,或你自己的。这是MDN的一个很好的例子。
let arr = [3,5,7];
/ pre>
arr.foo =hello;
(让我在arr中){
console.log(i); // log0,1,2,foo这些属性名称或索引
}
for(let i of arr){
console .LOG(ⅰ); // logs3,5,7这些是数组原型提供的
//可迭代实现的实际值
}
let
关键字在此上下文中与var
定义(虽然它有更多的含义,但它们不在本文的范围之内)。
正如你所看到的那样, code> iterable 接口(从数组原型),因此当使用循环的
时,它会产生它的值,而
所以如果你的对象没有实现
iterable
接口,它不应该是可迭代的(原则上),因此它将显示其属性在for ... of
循环。I was just wondering if there is a way to make an object property enumerable like in a
for in
loop but not show up in afor of loop
sort of likeObject.defineProperty({},'prop',{ enumerable:true, iterable:false }
if not, are there any plans to implement a feature like this? Or does the
for of
loop use the enumerable property解决方案I did some digging around at the Mozilla Development Network (MDN).
Turns out that objects have a
obj.propertyIsEnumerable(prop)
method to check if the property is enumerable. From the examples given in the MDN, properties inherited through the prototype chain are not enumerable, thus the method returns false for those properties.An example of non enumerable properties are constructors and the property
length
of arrays.For the iterable part of the question, I will quote MDN: "Iterable in ECMAScript 6 is an interface (or in other words, a protocol), not a type of object like Array or Map".
That is to say, the object needs to implement this interface to make its properties iterable. This is the case for built in iterables such as String, Array, Map, Set, WeakSet and Generator objects.
The following code illustrated this:
var aString = "hello" typeof aString[Symbol.iterator] // "function" aString[Symbol.iterator]() + "" // "[object String Iterator]" [...aString] // ["h", "e", "l", "l", "o"]
Of course, you can define your own iterator implementation.
Coming back to the question, properties attached to the object or its prototype (directly, meaning not via inheritance) will be displayed as enumerable in the
for...in
loop. For the iterables you need an implementation, either the ones mentioned before, or your own. Here is a great example from MDN.let arr = [ 3, 5, 7 ]; arr.foo = "hello"; for (let i in arr) { console.log(i); // logs "0", "1", "2", "foo" these are property names or indexes } for (let i of arr) { console.log(i); // logs "3", "5", "7" these are actual values of an // iterable implementation provided by the array prototype }
The
let
keyword is equivalent in this context to avar
definition (though it has more implications but they are outside the scope of this post).As you can see the array has an implementation already of the
iterable
interface (from the array prototype), thus it yields its values when using thefor...of
loop, whereas thefoo
property is not displayed (neither value nor property name).So if your object does not implement an
iterable
interface, it should not be iterable (in principle) and thus it will display its properties' in afor...of
loop.这篇关于你可以在javascript中创建属性可枚举但不可迭代吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!