2015-04-02 15 views
1

在JavaScript中,我經常使用||運算符來獲取某個屬性的值 - 或者默認值。例如:如何在JavaScript中「默認」布爾屬性?

var dens = mapping.defaultElementNamespaceURI||mapping.dens||''; 

如果mappingdefaultElementNamespaceURI,將使用它,否則找dens或默認使用一個空字符串。

但是,如果我的財產是布爾值,它不工作:

var dom = mapping.allowDom || mapping.dom || true; 

返回true即使mapping.domfalse

我想知道,什麼是最好的(簡潔但仍然可讀)的默認布爾屬性的語法?默認情況下,如果該屬性已定義,則使用其值,否則某些值會提供默認值。我可以爲此寫一個函數,但是也許有些像a || b || c那麼優雅?

代碼示例:

var a = {}; 
 
$('#result').text(a.boo||a.b||true);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> 
 
<pre id="result"></pre>


更新

好像沒有 「語法甜蜜」 的方式來做到這一點,所以我已經使出寫作功能:

var defaultValue = function() 
{ 
    var args = arguments; 
    if (args.length === 0) 
    { 
     return undefined; 
    } 
    else 
    { 
     var defaultValue = args[args.length - 1]; 
     var typeOfDefaultValue = typeof defaultValue; 
     for (var index = 0; index < args.length - 1; index++) 
     { 
      var candidateValue = args[index]; 
      if (typeof candidateValue === typeOfDefaultValue) 
      { 
       return candidateValue; 
      } 
     } 
     return defaultValue; 

    } 
} 

將最後一個參數視爲默認值。返回與默認值類型相同的第一個參數。

+0

你必須明確地測試值。如果你正在處理config * objects *,你也可以編寫一個簡單的合併函數,只有在屬性不存在時纔會複製該屬性。 – 2015-04-02 21:59:40

+1

你基本上都是堅持'typeof'測試或'==='測試(以一種可行的方式,而不是我刪除的答案:) – Pointy 2015-04-02 22:00:01

+0

是的!誤解,並刪除我的評論:] – Patrick 2015-04-02 22:01:39

回答

2
a.x || b 

如果a.x是「falsey」 - 未定義,空字符串,0,其他幾個值將返回b的值。

如果您需要顯示某些內容,除非該字段位於對象中,即使該字段的值爲falsey,您也必須明確地這樣說。

'x' in a ? a.x : b 

如果您明確將a.x設置爲undefined,則該表達式將返回'undefined',而不是b。

0

當涉及到那些對於布爾空測試選項是要走的路:

var dom; 
if (mapping.allowDom != null) { 
    dom = mapping.allowDom; 
} else if (mapping.dom != null) { 
    dom = mapping.dom; 
} else { 
    dom = true; 
} 

我想包上面的函數或也許單子。請注意,這是我使用==!=運營商的唯一用例,其他任何比較始終是運營商的===!==。因爲== null將測試爲null或未定義。

+0

不太確定爲什麼通過'!='運算符比較布爾或可能缺少的屬性與'null'。 – lexicore 2015-04-02 22:16:23

+0

你也可以用'mapping.allowDom!== false'進行比較,但是我發現'!= null'對我更具表現力。它也是您從CoffeeScript的默認參數語法獲得的相同輸出。 – Sukima 2015-04-03 12:11:36

0

OR運算符將返回第一個'truthy'值,如果該值被評估爲false,它將檢查下一個直到最後一個值。

因此,只能將假或假的值作爲默認值作爲序列中的最後一個值。

+0

我有點意識到它是如何工作的,並詢問它是如何工作的。 :) – lexicore 2015-04-02 22:15:05

+0

@lexicore如果你意識到這種方式不起作用,那麼爲什麼如果你意識到這一點,你試圖讓它工作就像不工作? – 2015-04-03 00:20:27

+0

我只是指出你的回答並不回答我的問題。 – lexicore 2015-04-03 12:50:49

3

最接近的優雅,你會發現是:

var dom = mapping.allowDom ? mapping.allowDom : mapping.dom ? mapping.dom : true;

正如指出的那樣,這僅僅是一個存在檢查。爲了完整

var dom = mapping.allowDom != null ? mapping.allowDom : mapping.dom != null ? mapping.dom : true;

var dom = 'allowDom' in mapping ? mapping.allowDom : 'dom' in mapping ? mapping.dom : true;

更新:你可以做以下任一接受false值的更新功能是理想的,如果你有值的變量列表進行比較的。但是,如果我們比較的唯一的東西是2(我們控制設置/驗證mapping.thing),我的代碼如下所示。 (我也不知道怎麼你以後使用dom

var dom = mapping.allowDom || mapping.dom; 
dom = dom === undefined ? true : dom; 

任何超過2元,我可能會選擇你的方法。

+1

OP是否確定這是他想要的。我在這裏試了一下,http://jsfiddle.net/myra7x2m/,當它們的值錯誤時我就變成了真的。 – John 2015-04-02 22:26:35

+1

這都將失敗'FALSE'值以及作爲三元將繼續,如果值爲'FALSE',不只是當它的不確定等 – adeneo 2015-04-02 22:27:39

+0

有效點。我原來的評論問這是否是期望的結果。示例修改可能是這樣的:http://jsfiddle.net/myra7x2m/1/ – Tony 2015-04-02 22:29:57

1

它比接受的答案長得多,但是它應該能夠讓我明白你想要的東西。

var mapping = {dom: false}; 
var dom = typeof mapping.allowDom !== "undefined" ? mapping.allowDom : typeof mapping.dom !== "undefined" ? mapping.dom : true; 
$('#result').append("" + dom); 

更多關於這個小提琴的測試。

http://jsfiddle.net/myra7x2m/

+0

在'!= null'或'in'比較中使用'typeof'有沒有好處? – Tony 2015-04-02 22:43:46

+1

@Tony!= null是更好,如果他想它時,它是null或undefined我以爲是他想要的東西是真實的,但他可能只需要它時,它是不確定的,我不確定。只要我看到它的更新,我確實發佈了對你的答案的評論。 – John 2015-04-02 22:48:10

+1

@Tony哦,作爲比較,如果他想設定某種東西是未定義他而在你將不得不刪除的元素,而不是具有相同的作用,因此沒有太大的區別只是有不同的偏好。因此,in的唯一問題是如果元素字面上未定義,它將返回undefined。 – John 2015-04-02 23:00:06

1

執行另外一個不錯的方式是通過功能和開關無控制表達它是什麼讓一個更好的if/else塊:

dom = (function() { 
    switch (false) { 
     case mapping.allowDom == null: 
     return mapping.allowDom; 
     case mapping.dom == null: 
     return mapping.dom; 
     default: 
     return true; 
    } 
})(); 

你可以在這裏測試此

http://jsfiddle.net/w3jtsk5u/

如果你想知道,爲什麼我比較== null而不是!= null它仍然在工作,是我用switch(false)所以比較的值是錯誤的否定表達式。

緊湊的朋友,當然,你可以寫:

dom = (function(){switch(false){ 
    case mapping.allowDom == null: return mapping.allowDom; 
    case mapping.dom == null:  return mapping.dom; 
    default:      return true; 
}})(); 

仍然可讀:)

+0

我喜歡一個函數的概念,不是所有的東西都可以,或者我想我應該說應該放在一行上。是的,它是優雅的,但有時你放棄了可讀性和簡單的方法。 – John 2015-04-02 23:06:56