2012-10-01 38 views
2

比方說,我有一個JavaScript對象,如:如何遍歷JavaScript對象並檢查空值?

var obj = {}; 
obj.computers = {}; 
obj.computers.favorite = "Commodore 64"; 
obj.computers.popular = "Apple"; 

現在,我可以很容易地檢查像空:

if(obj != 'undefined' && obj != null) { 
    if(obj.computers != 'undefined' && obj.computers != null)) { 
     ..... 

正如你可以看到,如果我需要看看obj.computers.favorite已定,我必須在那裏嵌入一些條件邏輯。我們的一些物體深度達到3,4,5層。

這是我想什麼能夠做到:

var fav = obj.computers.favorite || 'Unknown'; 

但我意識到我需要包裝,在一些方法。例如:

​​3210

建議感激。

感謝

編輯

我檢查了 '未定義' 其實不是我所用。問這個問題時,它剛剛出現在我的腦海中。大聲笑

但我想知道,我可以包裝在一個try/catch並拋出默認值,如果異常嗎?

function(obj, default) { 
    try { 
     if(obj != null) { 
      return obj; 
     } else { 
      return default; 
     } 
    } catch(ex) { 
     return default; 
    } 
} 

此外,感謝Shusi指出冗餘變量。

+0

'OBJ = '未定義' && OBJ = null'是不正確的,因爲得到一個字符串值''undefined'',你會需要typeof。這是一個常見的錯誤。但無論如何,這是不必要的冗長。只要執行'obj!= null',它就會同時測試'undefined'。 –

+0

'getValueOrDefault(obj.computers.favorite,'Unknown')'會在obj.computers未定義時拋出異常。您必須將其包裝在一個字符串中,並執行增量對象分析。 – saml

+0

@saml正好。這是我想要避免的。我們的JS對象有時會變得非常深刻。我想我可以做一個try/catch並且返回默認的異常? – cbmeeks

回答

3

你可以用幫手函數來做到這一點。如果我正確理解你的問題,你的對象可能有任意深對象,並且你想訪問這些任意的嵌套屬性而不會混淆你的代碼。我建立了一個Nested函數,它可以讓你get()任意屬性,如果它們被設置,或者它們是默認的,如果它們不是。

var Nested = function() {}; 
// prop is a dot-separated path like "foo.bar.baz" 
Nested.prototype.get = function(prop, _default) { 
    var current = this; 
    $.each(prop.split("."), function(i, e) { 
     current = current[e] || undefined; 
     if (current == undefined) 
      return false; 
    }); 
    return current || _default; 
} 

然後你可以這樣寫代碼

var fav = obj.get("computers.favourite", "Linux"); 
// this emulates 
var fav = obj.computers.favourite || "Linux"; // throws error 

正如你所看到的,它不是這麼多的打字。當然,它不像正常使用Javascript ... Here is the fiddle

+1

錯誤,您需要將var聲明更改爲'var current = this;'並在代碼中'current = current [e] ||未定義;'。小提琴然後會正常工作。 –

+0

+1我更新了我的答案 – Raffaele

+0

你應該提到你的回答需要jQuery。 – DrCord

7

你真的可以寫:是否存在

function getValueOrDefault(str , obj, deflt){ 
    var a = str.split("."); o = obj; 
    for(var i =0; i < a.length; i++){ 
     o = obj[a[i]]; 
     if(!o){ 
      return deflt; 
     } 
    } 
     return o; 
} 

var obj = {}; 
obj.computers = {}; 
obj.computers.favorite = "Commodore 64"; 
obj.computers.popular = "Apple"; 
getValueOrDefault('computers.favorite', obj, 'Unknown'); 

(obj && obj.computers && obj.computers.favorite) || 'Unknown' 
+0

+1,但請參閱我對一般解決方案的回答,該解決方案不會使用許多'和'來混淆代碼,並且如果OP多次使用此模式則更有用。 – Raffaele

1

下面的函數將字符串作爲參數,並返回對象:在屬性分配給對象如不得使用VAR。 var obj.computers.favorite是語法錯誤。

+0

我想你可以交換'obj'和'deflt'參數並改變'o = obj || window'。 所以你可以寫'getValueOrDefault('obj.computers.favorite','unknown')' –

+0

是的,你是對的。但是這個解決方案對於上面的問題更具體。 – Anoop

1

不幸的是,沒有一種超級簡單的方法來解決這個問題,但是你不需要檢查null和undefined。因爲null和undefined都是falsey,你可以做:

if (obj && obj.computers) { 
    var fav = obj.computers.favorite || 'unknown'; 
} 

它實際上並沒有得到解決您的投訴是什麼,但它比你想象的有什麼痛苦少。

3

我寫這個是爲了幫助你處理你的一個問題:「我需要看看obj.computers.favorite是否設置爲」。

Object.prototype.isset = function (/* string */ full_path) 
{ 
    var props = full_path.split('.'); 
    var self = this; /* note that self is usually the window object */ 

    for (var ii = 0; ii < props.length; ++ii) 
    { 
     var prop = props[ii]; 
     var hasMoreComing = ii < props.length - 1 ? true : false; 

     if (self[prop] !== null && typeof self[prop] === 'object' && hasMoreComing) 
     { 
      self = self[prop]; 
      continue; // Move up one level. 
     } 
     else if (hasMoreComing) 
      return false; // ..because user queries a subproperty of a value type 

     return self.hasOwnProperty(prop); 
    } 
}; 

測試代碼:!

var test = {}; 

test.kuk = {}; 
console.log(test.isset('kuk')); // Prints true. 

test.kuk.fitta = {}; 
console.log(test.isset('kuk.fitta')); // Prints true. 

test.kuk.fitta = null; 
console.log(test.isset('kuk.fitta')); // Prints true. 

test.kuk.fitta = undefined; 
console.log(test.isset('kuk.fitta')); // Prints true 

delete test.kuk.fitta; 
console.log(test.isset('kuk.fitta')); // Prints false 

test.kuk.fitta = 123; 
console.log(test.isset('kuk.fitta.doesnt.exist')); // Prints false 
+0

這不適用於PHP isset,因爲它返回true和undefined。 – DrCord