2017-02-14 37 views
-1

我想要的東西像Python's defaultdict in Javascript,除了沒有使用任何庫。我意識到這不會存在於純Javascript中。然而,有沒有辦法在合理數量的代碼中定義這種類型(不只是將一些大型庫複製並粘貼到我的源文件中),以後不會碰到不合需要的角落情況?Javascript defaultdict無庫

我希望能夠寫出下面的代碼:

var m = defaultdict(function() { return [] }); 
m["asdf"].push(0); 
m["qwer"].push("foo"); 
Object.keys(m).forEach(function(value, key) { 
    // Should give me "asdf" -> [0] and "qwer" -> ["foo"] 
}); 

我需要這在最近版本的火狐,Chrome,Safari和理想邊緣的工作。

再次,我做不是想盡可能使用庫。我想要一種以最小化依賴關係的方式來做到這一點。

原因,以前的答案不工作:

This answer使用庫,所以它沒有我最初的標準。另外,它提供的defaultdict實際上並不像JavaScript對象。我不打算在Javascript中編寫Python,我期望讓我的Javascript代碼更輕鬆。

This answer建議定義get。但是你不能用這個來定義集合類型的defaultdict(例如列表圖)。我不認爲這種方法也可以與Object.keys一起使用。

This answer提到代理服務器,但對我來說不是很明顯,您必須實施多少種方法才能避免出現漏洞,這些漏洞會在晚些時候導致惡劣的病例。編寫所有的代理方法當然看起來很痛苦,但是如果你跳過任何方法,如果你嘗試使用你沒有實現處理程序的東西,那麼你可能會爲自己造成痛苦的錯誤。 (紅利問題:您需要實施哪些最小代理方法以避免出現此類漏洞?)另一方面,建議的getter方法不遵循標準對象語法,而且您也不能做像Object.keys的事情。

+0

這是不打算回答你的問題,但它可能是考慮有用的東西你試圖用這種方式來實現,而不是試圖用你熟悉的方式(來自另一種語言)來解決問題。 –

+0

[定義的getter和setter](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Working_with_Objects#Defining_getters_and_setters)以何種方式不適合您的目的? – Hamms

+0

@AlexSzabó這是試圖讓典型的嵌套地圖模式不那麼痛苦。即我有一個類型,它在概念上是一個映射'a - > b - > c',我希望能夠編寫像'var x = defaultdict(function(){return {};}); x [「a」] [「b」] = 1;'如果下一級數據結構存在,則沒有每個級別的檢查樣板。如果有更好的方法比我建議的更好,請賜教。 –

回答

2

你真的好像在尋找一個proxy。它在您提到的現代瀏覽器中可用,不是庫,並且是唯一允許您保持標準對象語法的技術。使用代理其實原因很簡單,你只需要覆蓋的是get陷阱,應自動創建不存在的屬性:

function defaultDict(createValue) { 
    return new Proxy(Object.create(null), { 
     get(storage, property) { 
      if (!(property in storage)) 
       storage[property] = createValue(property); 
      return storage[property]; 
     } 
    }); 
} 

var m = defaultdict(function() { return [] }); 
m["asdf"].push(0); 
m["qwer"].push("foo"); 
Object.keys(m).forEach(console.log);