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)) { 
    ... 
}