4

在javascript中,我有很多這樣的代碼。javascript ignore-if-null運算符?

if (ctrl && ctrl.main && ctrl.main.user) { 
    SetTheme(ctrl.main.user.theme); 
} 

這是令人討厭的長。在其他語言中,你可以做簡單的

SetTheme(ctrl?.main?.user?.theme); 

有沒有辦法做到這一點在JavaScript?

我試過,

function safeGet(a,b) { return a ? a[b] : null; } 

SetTheme(safeGet(safeGet(safeGet(ctrl, 'main'), 'user'), 'theme')); 

但是,這不是很可讀。

+0

在JavaScript邏輯運算符&&''是你最好的選擇。無論如何,這似乎更像是一個關於JS的咆哮,而不是一個問題。 – Timo

+0

是的,對不起。重寫爲不太rantish –

+0

@Timo他要求的解決方案 - 不僅咆哮 – hack3rfx

回答

1

function getValue(object, prop, /*optional*/ valIfUndefined) { 
      var propsArray = prop.split("."); 
      while(propsArray.length > 0) { 
       var currentProp = propsArray.shift(); 
       if (object.hasOwnProperty(currentProp)) { 
        object = object[currentProp]; 
       } else { 
        if (valIfUndefined) { 
         return valIfUndefined; 
        } else { 
         return undefined; 
        } 
       } 
      } 

      return object; 
     } 

然後像任何物體上使用此正確的捷徑可能是

if (((ctrl || {}).main || {}).user) { // ... 

或者你可以使用數組作爲路徑或點將字符串分隔爲路徑並檢查aginst是否存在並返回值。

function getValue(object, path) { 
 
    return path.split('.').reduce(function (o, k) { 
 
     return (o || {})[k]; 
 
    }, object); 
 
} 
 

 
var ctrl = { main: { user: { theme: 42 } } }; 
 

 
console.log(getValue(ctrl, "main.user.theme"));

+1

非常好。我喜歡使用'||'。 –

1

你可以創建一個通用的功能通過將其代表的路徑到你想要的嵌套屬性字符串要做到這一點:

// This will return null if any object in the path doesn't exist 
if (getValue(ctrl, 'main.user', null)) { 
    // do something 
} 
+0

OP提到缺乏可讀性 – hack3rfx

+0

我認爲缺乏可讀性是參照嵌套的「saveGet」調用。這個解決方案不會遇到這個問題。 – mcgraphix

+0

確實,我想你不能太挑剔與JS – hack3rfx