簡體   English   中英

你可以在javascript中使屬性可枚舉但不可迭代嗎?

[英]Can you make properties enumerable but not iterable in javascript?

我只是想知道是否有一種方法可以使對象屬性可枚舉,就像在for in循環中但不會出現在for of loop類似

Object.defineProperty({},'prop',{
    enumerable:true,
    iterable:false
}

如果沒有,有沒有計划實現這樣的功能? 或者for of循環使用了enumerable屬性

我在Mozilla開發網絡(MDN)上做了一些挖掘工作。

原來,對象有一個obj.propertyIsEnumerable(prop)方法來檢查屬性是否可枚舉。 根據MDN中給出的示例,通過原型鏈繼承的屬性不可枚舉,因此該方法對這些屬性返回false。

不可枚舉屬性的一個示例是構造函數和數組的屬性length

對於問題的可迭代部分,我將引用MDN:“ECMAScript 6中的Iterable是一個接口(或者換句話說,一個協議),而不是像Array或Map這樣的對象類型”。

也就是說,對象需要實現此接口以使其屬性可迭代。 這是內置迭代的情況,例如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"]

當然,您可以定義自己的迭代器實現。

回到這個問題,附加到對象或其原​​型的屬性(直接,意思不是通過繼承)將在for...in循環中顯示為可枚舉。 對於iterables,您需要一個實現,或者前面提到的實現,或者您自己的實現。 這是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
}

let關鍵字在此上下文中與var定義等效(盡管它具有更多含義,但它們超出了本文的范圍)。

正如您所看到的,數組已經具有iterable接口的實現(來自數組原型),因此在使用for...of循環時會產生其值,而不顯示foo屬性(既不是值也不是屬性名稱) 。

因此,如果您的對象沒有實現iterable接口,那么它不應該是可迭代的(原則上),因此它將在for...of循環中顯示其屬性。

for infor of評估之間的區別在於,一個使用obj.[[enumerate]] ,另一個使用GetIterator(obj)來確定循環項。 [[enumerate]]確實 (除非obj是代理)

返回一個Iterator對象,next方法遍歷obj的可枚舉屬性的所有String值鍵。

GetIterator將(嘗試)調用@@iterate方法 - 但是,普通對象不實現此接口。

因此for of除非您明確說明,否則沒有屬性會出現在循環中:

function defineIterableProperty(obj, prop, desc) {
    let old = obj[Symbol.iterate];
    Object.defineProperty(obj, prop, desc);
    obj[Symbol.iterate] = function* () {
        if (old) yield* old.call(this);
        yield prop;
    };
    return obj;
}

(未經測試,但我希望你能得到這個想法)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM