2017-05-30 60 views
-2

我想知道为什么下面两个表达式返回相同的结果,即当val_bool始终是一个布尔[truefalse]:三元操作和这个选择有什么区别?

('oninput' in document.documentElement && !val_bool) && 'first result' || 'second result'; 

('oninput' in document.documentElement && !val_bool) ? 'first result' : 'second result'; 

如果你打开控制台并运行以下命令:

var val_bool = true; 
('oninput' in document.documentElement && !val_bool) && 'first result' || 'second result'; 

second result输出。相同的结果被输出时,我做出改变三元:

var val_bool = true; 
('oninput' in document.documentElement && !val_bool) ? 'first result' : 'second result'; 

我不熟悉与所述第一逻辑表达式解析其结果的机制。

+1

相关阅读:https://en.wikipedia.org/wiki/Short-circuit_evaluation – apsillers

+1

您是否使用开发控制台来测试这两个语句?他们表现不一样 – zzzzBov

+0

另外,你可能会得到低价,因为它不完全清楚你不明白的东西。我不认为这是你的错*(你不知道你不知道什么),但它确实使问题难以回答。你是否已经理解布尔逻辑运算符的机制以及短路是如何工作的?你知道JS中的逻辑运算符是如何将它们的操作数作为“真理”还是“虚假”? – apsillers

回答

1

三元表达式x ? y : z第一部分评估为布尔值并返回相应的值。

在另一行代码x && y || z的东西是不同的:它基本上是2倍的表达,而不是1

此链接在这里很有用:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Operator_Precedence

我们可以看到,&&||已经离开,TO- rigth associativity,这意味着左边的部分首先被评估。以下行是相等的:

x && y || z 
(x && y) || z 

表达x && y首先计算,并且x && y || z变得result(x,y) || z

实施例时的结果不同而输入是相同的:

const logical = (x, y, z) => x && y || z; 
 
const ternary = (x, y, z) => x ? y : z; 
 

 
console.log(
 
    logical(1, 0, 1) // 1 && 0 || 1 => 0 || 1 => __ 1 __ 
 
) 
 

 
console.log(
 
    ternary(1, 0, 1) // if (1) then 0; otherwise 1 => __ 0 __ (Boolean(1) === true) 
 
)

+0

非常感谢。我在[逻辑运算符](https:// github。)上找到了这篇文章。COM/getify /你,不要神秘JS/BLOB /主/类型%20%20grammar/ch4.md#运营商 - 和 - )。在*运算符'''和'&&'*下面我发现了这样一句话:“一个'||'或'&&'表达式的结果总是一个操作数的底层值,而不是(可能被强制的)考试。”我一直认为评价方式是布尔值,而不是基础值... –

+0

看过一些例子后,现在它变得更清晰了。将张贴答案只是为了解决我发布的实际问题。 –

+0

我很高兴能帮到你。 – wostex

0

只是张贴这为后代。

我在Logical Operators上找到了一篇报价的宝石。根据运营商||和& &,一个段落读取:

一个||&&表达的结果总是的操作数中的一个 基础值,不测试的(可能被迫)结果。

事实证明,我从评估的角度看待事物,而不是根本价值。

所以我最初的问题有以下表现:

('oninput' in document.documentElement && !val_bool) && 'first result' || 'second result'; 

让我们用简单的变量替换操作数:

var a = true; 
var b = true; 
var c = 'first result'; 
var d = 'second result'; 

(a && !b) && c || d; 

首先,(a && !b)将评估为false,因为atrue!bfalsetrue && falsefalse

其次,false结果将与c(false) && c)评估。再次,我们以false结束,因为c将评估为字符串(true),并且false && truefalse

最后,false结果将与d评估,只是这一次的操作是||false || true评价是true。然而,这不是评估将返回,而是潜在的价值,这是second result

当然,当我更新的btrue原值false事情会改变。 ||左侧的所有内容都会评估为true,因此当您评估true || true时,您会得到true,但哪个是true是问题。这是||左边的true,因为如果我们评估'a' || 'b',结果将是'a'。

所有收费的,它不等同于函数中的三元运算符,但两个特定表达式[如果变量类型保持不变]的结果应该是相同的。