优先级:逻辑或 vs. 三元运算符

5
请考虑以下内容:
(编辑:我稍微修改了函数,以消除三目运算符中使用括号的情况)
function someFunction(start,end,step){
  var start = start || 1,
      end = end || 100,
      boolEndBigger = (start < end);   // define Boolean here
      step = step || boolEndBigger ? 1:-1;
  console.log(step); 
}

someFunction()
// step isn't defined so expect (1<10) ? 1:-1  to evaluate to 1

someFunction(1,10)  
// again step isn't defined so expect to log 1 as before

The problem:

someFunction(1,10,2) 
//step IS defined, shortcut logical OR || should kick in, 
//step should return 2 BUT it returns 1

我知道这个问题很容易通过使用大括号来解决:

function range(start,end,step){
  var start = start || 1,
      end = end || 100,
      step = step || ((start < end) ? 1:-1);
  console.log(step); 
}

问题: 为什么在这种情况下“||”运算符不会被快捷方式替代? 我知道逻辑或(Logical OR)是二元逻辑条件运算符中优先级最低的,但我认为它比条件三元运算符具有更高的优先级? 我是否误读了MDN运算符优先级文档

5
"higher precedence" 的意思是您的代码被视为 (step || (start < end)) ? 1 : -1 进行评估。 - Niet the Dark Absol
@NiettheDarkAbsol:这意味着三元运算符具有更高的优先级,对吗?MDN文档说得不一样... - Pineda
@Xufox:如果是这样的话,第三次调用应该返回2。但它没有... - Pineda
我已经编辑了我的问题,以澄清我的提问内容... - Pineda
它不会捷径,因为它最终成为三元运算符的输入,但看起来你最终已经理解了这一点。 - Chris McCowan
显示剩余4条评论
2个回答

12
是的,|| 运算符的优先级高于条件运算符 ?:。这意味着它会先执行。来自你链接页的解释如下:
    运算符优先级决定了运算符被计算的顺序。优先级高的运算符优先被计算。
让我们看一下所有的操作:
step = step || (start < end) ? 1:-1;

优先级最高的运算符是()分组操作符。在这里,它导致结果为false

step = step || false ? 1 : -1;

下一个最高的优先级是逻辑 OR 运算符。 step 是真值,因此结果为 step

step = step ? 1 : -1;

现在我们进行三元操作,这是唯一剩下的操作。同样,step 是真值(truthy),因此执行第一个选项。

step = 1;

1
我明白了。但是我不理解为什么在这种情况下当左侧条件为真时 || 没有捷径? - Pineda
2
@Pineda 是的。它的左操作数是 step,右操作数是 falsefalse 从未执行。 - lonesomeday
啊等等……我想我明白了,我的假设是false ? 1 : -1算作||的第二个条件,而不仅仅是false - Pineda
2
@Pineda 是的,右手边直到下一个运算符是操作数,不是右边的所有内容。想象一下如何执行 5 + 2 * 3 + 4* 的优先级高于 + ,所以首先执行 2*3 - lonesomeday
谢谢。我明白了。我已经修改了我的问题,去掉了括号。虽然三元运算符中的括号被移除后优先级发生了变化,但我仍然遇到了错误。 - Pineda
显示剩余2条评论

1

JavaScript是一种弱类型语言,这意味着无论何时运算符或语句需要特定的数据类型,JavaScript都会自动将数据转换为该类型。

让我们看看它如何转换为其他类型

示例1。

如果()语句需要布尔值,则括号中定义的任何内容都将转换为布尔值。

JavaScript值通常被称为“真实”或“虚假”,根据这种转换的结果(即true或false)。请记住,除非已知为falsey,否则值为真实。

幸运的是,只有六个falsey-

  1. false(当然!)
  2. 未定义
  3. null
  4. 0(数字零)
  5. ""(空字符串)
  6. NaN(不是数字)

示例2。

var x = zoo || star ;

如果zoo评估为true,则返回zoo的值,否则返回star的值

示例3。

var str = '1' || '2';

"

'1'不是假值,因此将返回'1'。结果:str ='1';

示例4。

"
var str = '1' || (true) ? '2' : '3';

首先,||(逻辑或)运算符的优先级高于?(条件)运算符。
因此,首先评估('1' ||(true))。
'1' 不是 falsy 值,因此将返回 '1'。
中间结果:str = '1'?'2':'3'
'1' 不是 truthy 值,因此将返回 '2'。
最终结果:str = '2'。
示例 5。
var str = '1' || (false) ? '2' : '3';

首先,||(逻辑或)运算符的优先级高于?(条件)运算符
所以首先会计算('1'||(false))
'1'不是假值,因此将返回'1'
中间结果:str = '1'? '2':'3'
'1'不是真值,因此将返回'2'
最终结果:str = '2'
现在,在您的情况下很容易理解 :)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接