4

I was experimenting with having multiple arguments in an if statement on both sides of the logical operator. I first started with the || operator, which worked as expected:

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
}

So far, no unexpected results. However, when following a similar structure when replacing the || operator for the && operator, things don't quite work as I expect them to.

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
}

Now, I am wondering: is there a flaw in my logic or can it just not be done this way? My aim is to write these if statements as short as possible, for the purpose of readibility and maintainability. Clearly I am just exploring possibilities.

Does anyone know any way to go about this? Especially example 7/7a/7b seems peculiar to me because it yields inconsistent results despite a similar structure [Fiddle]

4

5 回答 5

2

Logical OR操作员不能以您正在寻找的方式工作。

如果可以转换为 true,则返回 expr1;否则,返回 expr2。因此,当与布尔值一起使用时,|| 如果任一操作数为真,则返回真;如果两者都为假,则返回假。

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语句,因为它们已经很短了我认为可读。

if ( "apple" === a || "banana" === a ) { ... }
于 2014-03-02T09:24:42.117 回答
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'

于 2014-03-02T09:23:13.977 回答
0

(a || b) == 'banana'总是为假,因为(a || b)将返回布尔女巫不等于字符串

更新:做一些测试(a || b)总是返回第一个操作数(a在这种情况下)女巫是“苹果”而不等于“香蕉”。

|| 只有当两个操作数都是布尔值或可以转换为布尔值时,&& 才会给出例外结果。

于 2014-03-02T09:24:09.497 回答
0

它的工作方式是这样的,a && b并且a || b总是设置为变量之一的值。a && b将始终设置为b除非a是的值false,在这种情况下,答案必须是false。同样a || b将设置为 的值a,除非afalse,在这种情况下,它将设置为 的值b。正如 elclanrs 所提到的,这是因为短路评估 - 第一个操作数可能会决定结果,在这种情况下,查看第二个操作数是没有意义的。

ab都是字符串时,除非字符串长度为零,否则它们永远不会为假。a || b在您的情况下将是“苹果”,将a && b是“香蕉”。

于 2014-03-02T09:27:22.647 回答
0

作为替代解决方案,您可以使用someor every

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)) {
  ...
}
于 2014-03-02T09:29:26.963 回答