JavaScript中的哈希表(Hash Maps的最佳實踐)
注* 散列表(Hash table,也叫哈希表),是根據關鍵字(Key value)而直接訪問在內存存儲位置的數據結構。摘自 Wiki
Hash Map通常在JavaScript中作為一個簡單的來存儲鍵值對的地方。然而,Object并不是一個真正的哈希映射,如果使用不當可能會帶來潛在的問題。而且JavaScript可能不提供本地哈希映射(至少不是跨瀏覽器兼容的),有一個更好的聲明對象屬性的方法。
在Object聲明成員的問題
該問題可能緣于對象原型鏈的繼承機制。就拿toString方法來說,如果使用in操作符來判斷對象是否存在的話:
var map = {};'toString' in map; // true
因為in操作符會從所有原型繼續對象查找該對象是否存在。要解決這個問題,可使用hasOwnProperty方法檢測該對象是否存在:
var map = {};map.hasOwnProperty('toString'); // false
這個方法可以工作地很正常,不過如果你定義了一個hasOwnProperty屬性那可能就麻煩了:
var map = {};map.hasOwnProperty = 'foo';map.hasOwnProperty('hasOwnproperty'); // TypeError
快速修復這個的方法是使用原生對象的方法。
var map = {};map.hasOwnProperty = 'foo';{}.hasOwnProperty.call(map, 'hasOwnproperty'); // true
這種方法不會引起任何問題,每次你判斷對象中的屬性是否存在時都要過濾掉原型鏈中的方法:
var map = {};var has = {}.hasOwnProperty;for(var key in map){if(has.call(map, key)){// do something}}
裸對象
創建一個真正的Hash Map的訣竅是解藕所有的原型對象。我們可以通過 Object.create 來實現這個效果
var obj = {};// is equivalent to:var obj = Object.create(Object.prototype);
另外,這種方法可以讓你完全放棄原型,直接使用 null 來繼承。
var map = Object.create(null);map instanceof Object; // falseObject.prototype.isPrototypeOf(map); // falseObject.getPrototypeOf(map); // null
這些裸對象(或字典)是作為Hasp Map的理想選擇。因為不會有任何沖突,它會抵制任何類型轉換,比如這樣就會產生錯誤。
var map = Object.create(null);map + ""; // TypeError: Cannot convert object to primitive value
這里沒有任何保留字,它就是為Hash Map設計的,比如。
var map = Object.create(null);'toString' in map; // false
更進一步,for ... in 循環變得更加簡單了,我們只需要把循環寫成這樣。
var map = Object.create(null);for(var key in map){// do something}
除了這些區別,它使用起來跟一般的Object鍵值存儲沒有任何區別。該對象可以被序列化,可以聲明原型和被繼承,上下文變量的使用也是一樣的。
var map = Object.create(null);Object.defineProperties(map, {'foo': {value: 1,enumerable: true},'bar': {value: 2,enumerable: false}});map.foo; // 1map['bar']; // 2JSON.stringify(map); // {"foo":1}{}.hasOwnProperty.call(map, 'foo'); // true{}.propertyIsEnumerable.call(map, 'bar'); // false
甚至上面提到的那些變量檢測方法同樣適用。
var map = Object.create(null);typeof map; // object{}.toString.call(map); // [object Object]{}.valueOf.call(map); // Object {}
本文由用戶 gf67 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!