2015-09-04 102 views
8

JavaScript WeakMap(https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/WeakMap)不允許您通過設計獲得密鑰或長度或大小。如何遍歷弱映射?

是否有可能以某種方式循環條目?

如果不是,Chrome控制檯如何做到這一點?

enter image description here

+0

不,弱映射不可迭代。控制檯可以實現魔法(嘿,它同時也顯示了promise的價值)。 – Bergi

+0

好的 - 我想要做那個魔法,有什麼建議嗎? :-D – commonpike

+0

編寫一個使用調試接口的應用程序,然後:-) – Bergi

回答

10

是否有可能仍然遍歷以某種方式記錄?

沒有,就像你說的,一個WeakMap的內容不是由設計訪問,並沒有iterability。

如果不是... Chrome控制檯如何做到這一點?

控制檯使用JS引擎的調試API,它允許對對象的訪問的內部(也答應狀態,原語包裹等)等等。

+1

自從我讀了這個答案後,我開始注意到在Chrome控制檯中更奇怪的魔法。在極少數情況下,控制檯在試圖跟蹤代碼時,也可以輸出未來的數據:-) – commonpike

+0

@commonpike:該特定行爲在[這裏]解釋(http://stackoverflow.com/q/23392111/ 1048572)。 – Bergi

+0

那些看起來像來自未來的價值觀相對於過去,但不會比現在更進一步。 :} – trusktr

0

你可以使用這個小片段的通用for each。但它使用lodash並且可以大大增強。

import lodashForEach from 'lodash/forEach'; 
import entries from 'lodash/entries'; 
/** 
* @since [email protected] 
* @param {Array|Map|Object|Set|WeakMap|WeakSet} iterable 
* @param {Function} iteratee 
* @example 
* const iterable = new Map(); 
* iterable.set('somekey1', 1); 
* iterable.set('somekey2', 2); 
* // or 
* const iterable = new Set(); 
* iterable.add("entry1"); 
* iterable.add("entry2"); 
* // run function 
* forEach(iterable, (value, key) => { 
* console.group('-'); 
* console.info('KEY'); 
* console.log(key); 
* console.info('VALUE'); 
* console.log(value); 
* console.groupEnd(); 
* }); 
*/ 
function forEach(iterable, iteratee) { 
    lodashForEach((iterable instanceof Set || iterable instanceof WeakSet) ? Array.from(iterable) : entries(iterable), (entry, index, collection) => { 
     iteratee(entry[1], entry[0], collection, index); 
    }); 
    return iterable; 
} 

export default forEach; 

UPDATE

後好長一段時間,我發現這個答案不正確。東西是舊版核心 - js填充庫有固定的bug,它取代原生WeakMap實施與自己的。所以我的解決方案在現代瀏覽器中無效。

function forEach(iterable, iteratee) { 
    switch (true) { 
     case Array.isArray(iterable) || iterable instanceof Map: 
      iterable.forEach(iteratee); 
      break; 
     case iterable instanceof Set: 
      Array.from(iterable).forEach(iteratee); 
      break; 
     case iterable instanceof WeakMap || iterable instanceof WeakSet: 
      // some kind of warning 
      break; 
     default: 
      Object.keys(iterable).forEach((key) => iteratee.call(null, iterable[key], key)); 
      break; 
    } 
    return iterable; 
} 
+1

問題是:WeakMaps不可迭代,所以此解決方案不適用。 myWeakMap.entries()。length == 0; 因此,對於WeakMap中的項目,不要調用iteratee。 –

+0

'Array.from(new WeakMap()。set({},{}))'...沒有運氣。 – Pacerier