2016-03-07 147 views
3

時間的理智,再次我不得不面對這樣的代碼考慮下列假設的例子:檢查JSON對象

if (node.data.creatures.humans.women.number === Infinity) { 
    // do-someting 
} 

現在,問題是,如果節點是未定義這個條件將打破。同樣,如果node.data未定義,node.data.creatures未定義等,則會中斷。

所以我最終使用了以下種類的長期條件:

if (node && node.data && node.data.creatures && node.data.creatures.humans && node.data.creatures.women && node.data.creatures.humans.women.number === Infinity) { 
    // do-someting 
} 

現在,想象一下我必須使用JSON對象的部分在代碼的其他許多地方也。

代碼突然開始顯得非常難看。有沒有更好的方法來避免由於我提到的第一個條件導致的「無法調用未定義的屬性」類型的錯誤,以便代碼看起來更好。

你如何處理這種情況?

+0

新的代理API(相當新,支持有限)可以輕鬆解決他的:https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Proxy – haim770

+0

作爲一個說明,它是一個JavaScript對象而不是_JSON object_。數據的JSON表示,如果以JSON格式解析數據,您將得到一個JavaScript對象作爲結果。 –

回答

0

試圖在undefined訪問屬性是開捕TypeError,所以你可以使用try..catch

try { 
    if (node.data.creatures.humans.women.number === Infinity) { 
     // do something 
    } 
} catch (e) { 
    // property doesn't exist 
} 
0

您可以try包裹潛在的有害部分 - catch

try { 
    if (node.data.creatures.humans.women.number === Infinity) { 
     // do-someting 
    } 
} catch() { 
    console.log(e); 
} 

另一種方式,也許更優雅一點是定義預期的對象結構,並使用例如0123將它們與實際數據合併。

var nodeTemplate = { 
    data: { 
     creatures: { 
      humans: {...} 
     } 
    } 
} 

這將確保結構如您期望的那樣並且不存在的字段具有一些默認值。

然後將其合併:

node = $.extend(nodeTemplate, node); 
0

這裏是我使用的東西,它可能不是 「optimizest」 的方式,但是,對於我的作品:

walkObject = function(obj, path) { 
    var i = 0, 
    part = void 0, 
    parts = path.split('.'); 

    while (obj && (part = parts[i++])) { 
    obj = obj[part]; 
    } 
    return obj; 
}; 

該方法採用一個對象和包含要測試的屬性的點符號的字符串:

// the object 
var obj = { a: { b: {c: [1,2,3], d: "aa"} } }; 

// tests 
console.log("a,b,c", walkObject(obj, 'a.b.c')); // [1,2,3] 
console.log("a,b,e", walkObject(obj, 'a.b.e')); // undefined 
console.log("z,b,e", walkObject(obj, 'z.b.e')); // undefined