3

我是用在邏輯運算符兩側的if語句具有多參數試驗的兩側。我首先從||開始運營商,如預期的那樣工作:多個條件的邏輯運算符

var a = 'apple', b = 'banana', c = 'cherry'; 

if (a == 'banana' || a == 'apple' || b == 'banana' || b == 'apple') { 
    console.log('example 1') // returns 
} 

if ((a || b) == 'banana' || (a || b) == 'apple') { 
    console.log('example 2') // returns 
} 

if (a == ('apple' || 'banana') || b == ('apple' || 'banana')) { 
    console.log('example 3') // returns 
} 

if ((a || b) == ('apple' || 'banana')) { 
    console.log('example 4') // returns 
} 

到目前爲止,沒有意外的結果。 但是,在替換||時遵循相似的結構運營商爲& &操作,事情並不像我期待他們合作。

if ((a == 'banana' && b == 'apple') || (a == 'apple' && b == 'banana')) { 
    console.log('example 5') // returns 
} 

if (((a || b) == 'banana') && ((a || b) == 'apple')) { 
    console.log('example 6') // DOESN'T RETURN 
} 

if ((a || b) == 'banana') { 
    console.log('example 6a') // DOESN'T RETURN - consistent with example 6 
} 

if ((a == ('apple' || 'banana')) && (b == ('apple' || 'banana'))) { 
    console.log('example 7') // DOESN'T RETURN 
} 

if (a == ('apple' || 'banana')) { 
    console.log('example 7a') // returns - inconsistent with example 7 
} 

if (b == ('apple' || 'banana')) { 
    console.log('example 7b') // DOESN'T RETURN - inconsistent with example 7a 
} 

if ((a && b) == ('apple' || 'banana')) { 
    console.log('example 8') // DOESN'T RETURN 
} 

if ('apple' == (a || b) && 'banana' == (a || b)) { 
    console.log('example 9') // DOESN'T RETURN 
} 

現在,我想知道:在我的邏輯中是否存在缺陷,或者它可能不會以這種方式完成?爲了可讀性和可維護性,我的目標是儘可能簡短地編寫這些if語句。顯然我只是在探索可能性。

有誰知道任何方式去嗎?特別是7/7a/7b的例子看起來很奇怪,因爲儘管結構類似,它仍然會產生不一致的結果 [Fiddle]

+0

不,不能那麼做,'(A || B) ==某些東西'是無效的JavaScript並失敗。 – adeneo

+0

(a || b)=='banana'應該是(a =='banana'|| b =='banana') – SajithNair

+2

作爲旁註,你可以做'if(/(banana|apple)/.test (a))' – adeneo

回答

2

Logical OR運營商並不在你正在尋找一種方式工作。

返回expr1的,如果它可以被轉化爲true;否則,返回expr2。因此,當與布爾值一起使用時,||如果任一操作數爲真,則返回true;如果兩者都是假的,則返回false。

MDN

一種替代方法可以是使用磁盤陣列的indexOf方法。請注意,它將返回數組元素的index,因此0也可以是有效的值。爲了使我們的if語句按預期工作,我們必須使用0 <= ...這樣的:

if (0 <= ["apple","banana"].indexOf(a)) { ... } 

你可以做的另一件事是使用in運營商。另外,作爲它只檢查對keys,你可以離開values空這樣的:

if (a in { "apple": "", "banana": "" }) { ... } 

如果你的選擇很多的,顯然這是更好地做到以下幾點:

var options = { 
    "apple": "", 
    "banana": "" 
} 

if (a in options) { ... } 

我個人認爲,只有兩個選項可以檢查,這對於人眼來說是兩個分開的檢查更具可讀性,並且我認爲在您的示例中,您並不需要縮短if語句,因爲它們已經很短且可讀我的想法是。

​​
1

如果您想要一個乾淨的方法來檢查一個變量是否等於任何其他變量中的任何一個,此:

http://jsfiddle.net/aYRmL/

function equalsAny (first) { 
    return !![].slice.call(arguments, 1).filter(function (val) { 
     return first === val; 
    }).length; 
} 

第一個參數是被比較於其餘部分的一個。像這樣使用它:

var a = 'banana', b = 'orange'; 
equalsAny(a, 'banana', 'apple'); // returns true 
equalsAny('orange', a, b); // returns true 

上面的第一個完成了你想用a == ('banana' || 'apple')做什麼。秒數完成了你想要用(a || b) == 'banana'做什麼。

+0

如果您通過了第一個參數作爲實際參數,然後切片數組的一個元素並鏈接過濾器。即http://jsfiddle.net/aYRmL/2/ – elclanrs

+0

@elclanrs是啊,這只是一個快速離我的頭頂。現在修好。 – aleclarson

0

(a || b) == 'banana'永遠是假的,因爲 (a || b)會返回一個布爾巫不等於字符串

UPDATE: 做了一些測試(a || b)總是返回第一個操作數(a在這種情況下)女巫「蘋果'並不等於'香蕉'。

||和& &將給只有在兩個操作數都是布爾或可以被包裝到布爾除外結果。

+1

JavaScript的'||'並不總是產生布爾值。它將按原樣返回「a」或「b」的值。 'console.log(1 || 2);'記錄'1',不是'true'。 –

+2

因爲[短路評估](http://en.wikipedia.org/wiki/Short-circuit_evaluation) – elclanrs

0

它的工作方式是,a && ba || b總是設置一個變量的值。 a && b將始終設置爲b的值,除非afalse,在這種情況下,答案必須是false。同樣a || b將被設置爲值a,除非afalse,在這種情況下,它將被設置爲值b。正如elclanrs提到的那樣,這是因爲短路評估 - 第一個操作數可能決定結果,在這種情況下,查看第二個操作數沒有意義。

ab都是字符串時,除非該字符串爲零長度,否則它們永遠不會爲假。所以a || b將在您的情況下爲'蘋果',而a && b將爲'香蕉'。

0

作爲一種替代解決方案,您可以使用someevery

var __slice = [].slice; 

function any(a) { 
    return __slice.call(arguments,1).some(function(x) { 
    return a === x; 
    }); 
} 

function all(a) { 
    return __slice.call(arguments,1).every(function(x) { 
    return a === x; 
    }); 
} 

而且使用像:

// Instead of: 
// if (a == 'banana' || a == 'apple' || a == 'orange') 
if (any(a, 'banana', 'apple', 'orange')) { 
    ... 
} 

// Instead of: 
// if (a == 'banana' && b == 'banana' && c == 'banana') 
if (all('banana', a, b, c)) { 
    ... 
}