摘要:然而,對象字面量不是真正意義上的哈希映射,如果使用不當可能會構成潛在的隱患。空對象創建一個真正的哈希映射的秘訣就是避免原型,及其帶來的包袱。在此之前,甚至之后,你應該使用空對象滿足你所有的基本哈希映射需求。
對象字面量存在的問題在JavaScript中存儲鍵值對的一個簡單常見的方法是使用對象字面量。然而,對象字面量不是真正意義上的哈希映射,如果使用不當可能會構成潛在的隱患。雖然目前JavaScript可能沒有提供原生的hashmap(至少不能跨瀏覽器),對象字面量如果沒有隱患就能達到所需的功能也許是一個更好的選擇。
對象字面的問題在于其原型鏈繼承自Object原型上的對象和方法會破壞其維持鍵值的機制。以toString方法為例,使用in操作符檢查同名屬性會導致錯誤的結果:
javascriptvar map = {}; `toString` in map; // true
上面的錯誤之所以會發生,是因為in操作符會從對象的原型鏈上查找繼承屬性。為了解決該問題,我們可以用hasOwnProperty方法來確定鍵值的存在性,因為該方法只檢查對象本身的屬性:
javascriptvar map = {}; map.hasOwnProperty("toString"); // false
上面的方法能夠良好的工作,除非你遇到一個名為hasOwnProperty鍵。重寫此方法將會因為嘗試調用hasOwnProperty方法而導致意外的行為,根據新的值最有可能導致錯誤:
javascriptvar map = {}; map.hasOwnProperty = "foo"; map.hasOwnProperty("hasOwnProperty"); // TypeError
一個快速的修正方法是利用一個通用且沒有被篡改的對象字面量,并在你指定的hashmap上下文中執行hasOwnProperty方法:
javascriptvar map = {}; map.hasOwnProperty = "foo"; {}.hasOwnProperty.call(map, "hasOwnProperty"); // true
盡管實際工作時沒有任何問題,但對象字面量還是限制了它的使用。舉個例子,每次你在for...in循環里面遍歷一個對象的屬性,你都要過濾其原型鏈中的屬性:
javascriptvar map = {}; var has = {}.hasOwnProperty; for (var key in map) { if(has.call(map, key)) { // ... } }
一段時間后,可能會變得有點乏味。值得慶幸的是,有一個更好的辦法。
空對象創建一個真正的哈希映射的秘訣就是避免原型,及其帶來的包袱。我們可以利用ES5中引入的Object.create方法達到該目的。該方法的特別之處在于你可以給一個新對象明確定義原型。舉個例子,用一個較復雜的方式定義一個簡單對象字面量:
javascriptvar obj = {}; // 等價于 var obj = Object.create(Object.prototype);
除了能夠定義一個你選擇的原型,你也能夠通過傳入一個null放棄傳入原型:
javascriptvar map = Object.create(null); map instanceof Object; // false Object.prototype.isPrototypeOf(map); // false Object.getPrototypeOf(map); // null
這些空對象對于哈希映射是理想的,因為缺少[[Prototype]]避免了命名沖突。由于該對象完全是空的,它會抵制任何形式的強制轉換,試圖這樣做將導致一個錯誤:
javascriptvar map = Object.create(null); map + ""; // TypeError: Cannot convert object to primitive value
空對象沒有任何初始值或者字符串表現形式,因為空對象除了作為鍵值對的存儲空間沒有為任何其他事情做打算,簡單又普通。
注意hasOwnProperty方法在空對象中也消失了,這無關緊要,因為in操作符可以無異常的工作了:
javascriptvar map = Object.create(null); "toString" in map; // false
更好的是,乏味的for...in循環變得更加簡單。我們最終可以按其本身的意思寫一個循環:
javascriptvar map = Object.create(null); for (var key in map) { // ... }
雖然存在差異,但對所有的意圖和目的,它仍然表現得就像一個對象字面量。屬性可以利用.或則[]訪問,對象可以被序列化,且對象仍然可以使用上下文對象的原型方法:
javascriptvar map = Object.create(null); Object.defineProperties(map, { "foo": { value: 1, enumerable: true }, "bar": { value: 2, enumerable: false } }); map.foo; // 1 map["bar"]; // 2 JSON.stringify(map); // {"foo": 1} {}.hasOwnProperty.call(map, "foo"); // true {}.propertyIsEnumerable.call(map, "bar"); // false
甚至不同檢查類型的方法將會告訴你從對象字面中期望得到什么:
javascriptvar map = Object.create(null); typeof map; // object {}.toString.call(map); // [object Object] {}.valueOf.call(map); // Object {}
這一切使得空對象代替對象字面量變得簡單,讓他們很好地集成到一個現有的應用程序,而不會引起大范圍的變化。
總結在簡單的鍵值存儲的背景下,使用空對象是對象字面量的有效替代方案,用明確的定義消除對象字面量的怪癖。對于更全面的數據結構,ES6將以Map和Set形式引入原生的hashmap。在此之前,甚至之后,你應該使用空對象滿足你所有的基本哈希映射需求。
歡迎光臨我的個人博客:風影博客
參考原文地址:True Hash Maps in JavaScript
Object.create()
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/92325.html
摘要:為了防止你錯過了之前的文章,以下是鏈接第一部分給開發者的源碼源碼結構第二部分理解內部函數的定義第三部分的變量實現所有的東西都是哈希表基本上,里面的所有東西都是哈希表。哈希后的結果可以被作為正常的數組的鍵值又名為內存塊。表示哈希表的容量。 文章來自:http://www.hoohack.me/2016/02/15/understanding-phps-internal-array-im...
摘要:正文在年,框架的選擇并不少。特別的,通過思考這些框架分別如何處理狀態變化是很有用的。本文探索以下的數據綁定,的臟檢查的虛擬以及它與不可變數據結構之間的聯系。當狀態產生變化時,只有真正需要更新的部分才會發生改變。 譯者言 近幾年可謂是 JavaScript 的大爆炸紀元,各種框架類庫層出不窮,它們給前端帶來一個又一個的新思想。從以前我們用的 jQuery 直接操作 DOM,到 Backb...
摘要:原文譯者插件能夠將引擎的全部潛力暴露給第三方的開發者。當將一個插件應用到環境中,這個插件將會獲得一個對于這個的引用。表示有關模塊資源,已編譯資源,已更改文件和監視依賴關系的當前狀態的信息。 原文:how to write a plugin 譯者:neal1991 welcome to star my articles-translator , providing you advanc...
摘要:使用能優雅的構建并且與單頁面應用程序完美結合。我們將重點關注所需的所有部分,然后在后續教程中,我們將進一步演示如何使用作為層。例如,如果用戶刷新路由,我們將需要匹配該路由并返回應用程序模板。運行應用程序該基礎用于構建具有和路由器的。 使用Laravel能優雅的構建API并且與Vue單頁面應用程序(SPA)完美結合。在本教程中,我們將展示如何啟動和運行Vue路由器以及用于構建SPA的La...
摘要:原文引言這篇文檔包含了如何避免使代碼性能遠低于預期的建議尤其是一些會導致牽涉到等無法優化相關函數的問題一些背景在中并沒有解釋器但卻有兩個不同的編譯器通用編譯器和優化編譯器這意味著你的代碼總是會被編譯為機器碼后直接運行這樣一定很快咯并不是 原文:http://dev.zm1v1.com/2015/08/19/javascript-optimization-killers/引言 這篇文檔包...
閱讀 1640·2023-04-25 20:36
閱讀 2049·2021-09-02 15:11
閱讀 1177·2021-08-27 13:13
閱讀 2653·2019-08-30 15:52
閱讀 4588·2019-08-29 17:13
閱讀 1001·2019-08-29 11:09
閱讀 1491·2019-08-26 11:51
閱讀 833·2019-08-26 10:56