2010-09-08 53 views
1

我需要一些JavaScript中的HashMap。我們可以這樣做:使用類似java Map的javascript對象?

var map = {}; 
map['foo'] = true; 
map['zoo'] = true; 
... 

if (map['foo']) { 
    // yes, foo exists. 
} 
else { 
    // no, foo does not exist. 
} 

如果不存在,我們如何正確檢查屬性的存在而不插入它?例如,我不想map.foo到,如果我沒有明確添加上述檢查後存在,

感謝

回答

9

在你的榜樣,檢查:

if (map['foo']) { 
    //.. 
} 

不僅檢查屬性是否未在對象上定義,則if語句的條件表達式也將評估爲false,如果該屬性在布爾上下文(又名falsy值)上持有強制爲false的值,例如0,NaN,空字符串,nullundefined當然false,例如:

var map = { 
    'foo': 0 // or any other falsy value 
}; 

if (map['foo']) { 
    // foo is truthy... 
} else { 
    // foo is falsy or not defined 
} 

要檢查屬性的對象上存在,無論價值哪位可以falsy,甚至undefined - ,你可以使用hasOwnProperty方法,例如:

var map = {}; 
map['foo'] = 0; 

if (map.hasOwnProperty('foo')) { 
    // foo exist physically on the object... 
} 

用這種方法唯一的問題是,如果有人添加一個名爲hasOwnProperty一個對象的屬性,它不會工作,例如:

var obj = { 
    hasOwnProperty: 'bar' 
}; 

如果執行obj.hasOwnProperty('prop'),它會給你一個TypeError,因爲對象包含陰影的方法-invoking字符串會導致無差錯的字符串屬性。

一種變通方法,這是直接從Object.prototype對象調用hasOwnProperty方法,例如:

if (Object.prototype.hasOwnProperty.call(obj, 'prop')) { 
    //.. 
} 

還可以使用in operator

if ('prop' in obj) { 
    //... 
} 

與第一種方法的區別是,in操作者檢查也可用於繼承的屬性,例如:

var obj = {}; 
obj.hasOwnProperty('toString'); // false 
'toString' in obj; // true, inherited from Object.prototype.toString 

參見:

編輯:

延長我的@slebetman評論迴應,有關檢查if (map.foo !== undefined)

當我在評論中,有關於訪問undefined全局屬性一些顧慮,也檢查屬性值財產存在之間的語義差別

undefined全局屬性沒有被定義爲只讀的ECMAScript第三版標準,(是ES5 :)

現在writable = false幾乎在所有實現它的價值可以被替換。

如果有人提出:

window.undefined = 'foo'; 

// It will break your code: 
var obj = {}; 
if (obj.foo !== undefined) { 
    alert("This shouldn't ever happen!"); 
} 

而且語義差別:通過測試,如果map.foo !== undefined我們不是在技術上只有當屬性的對象上存在或不檢查,一個屬性也存在,抱着不確定的值,例如:

var map = { 
    'foo': undefined 
}; 

map.hasOwnProperty('foo'); // true, because the property exists although 
          //  it holds the undefined value 
map.foo !== undefined;  // false 
+1

對於直接從Object對象創建的空對象(在本例中爲true),使用hasOwnProperty不是必需的。直接檢查該值是否未定義:'if(map.foo!== undefined)'。 – slebetman 2010-09-08 05:00:16

+0

@slebetman,是的,但有一些關於訪問未定義的全局屬性作爲標識符的疑慮1.不是ECMAScript 3的一部分(現在在ES5上定義:) 2.在某些實現中,不讀取屬性只有它的價值可以被取代,例如如果有人使'window.undefined = true;',它會破壞你的代碼。同時檢查'map.foo!== undefined',我們沒有在技術上檢查對象上是否存在屬性*,屬性*可以*存在,將'undefined'作爲值。 – CMS 2010-09-08 05:03:04

+0

@slebetman - 同樣考慮修改'Object.prototype'。在你的瀏覽器中試試這個:'javascript:Object.prototype.foo = 5; bar = {}; alert((bar.foo!== undefined)+「,」+ bar.hasOwnProperty(「foo」)); Object。 prototype.hasOwnProperty = function(){return true}; alert(bar.hasOwnProperty(「baz」))' – 2010-09-08 06:30:54

0

通過使用JavaScript Hashmap Equivalent

 
<html> 
<head> 
<script> 
HashMap = function(){ 
    this._dict = {}; 
} 
HashMap.prototype._shared = {id: 1}; 
HashMap.prototype.put = function put(key, value){ 
    if(typeof key == "object"){ 
    if(!key.hasOwnProperty._id){ 
     key.hasOwnProperty = function(key){ 
     return Object.prototype.hasOwnProperty.call(this, key); 
     } 
     key.hasOwnProperty._id = this._shared.id++; 
    } 
    this._dict[key.hasOwnProperty._id] = value; 
    }else{ 
    this._dict[key] = value; 
    } 
    return this; // for chaining 
} 
HashMap.prototype.get = function get(key){ 
    if(typeof key == "object"){ 
    return this._dict[key.hasOwnProperty._id]; 
    } 
    return this._dict[key]; 
} 


var color = {}; // unique object instance 
var shape = {}; // unique object instance 
var map = new HashMap(); 
map.put(color, "blue"); 
map.put(shape, "round"); 
console.log("Item is", map.get(color), "and", map.get(shape)); 
</script> 

<head> 
<body> 
<script>document.write("Existing Item Testing :\t\t\t" + map.get(color)+"
"); document.write("Non - Existing Item Testing :\t\t\t" + map.get("test")+ ""); </body> </html>

輸出:

Existing Item Testing : blue 
Non - Existing Item Testing : undefined 
0

Java Map和Java HashMap是不同的東西。 Java Map是一個哈希表,它具有鍵標記的值,並通過鍵快速搜索值。另一方面,如果您通過鍵或按值搜索值,則HashMap具有相同的密封時間。

我寫了一個類似於Java Map的數據結構,但我仍在開發JavaScript的HashMap類,我會盡快分享它。請注意,我的解決方案只是本地散列表的包裝,以便於使用和迭代。稍微放慢一點,消除時間,多一點記憶。

您可以檢查它在我的博客,因爲它是在這裏過長:http://stamat.wordpress.com/javascript-map-class/

謝謝你給它一個機會!反饋非常感謝! :)

相關問題