Javascript 三元运算符的运算符优先级
题
我似乎无法理解这段代码的第一部分( += )与三元运算符的结合。
h.className += h.className ? ' error' : 'error'
我认为这段代码的工作方式如下:
h.className = h.className + h.className ? ' error' : 'error'
但这是不正确的,因为这会在我的控制台中出现错误。
所以我的问题是我应该如何正确解释这段代码?
解决方案
h.className = h.className + (h.className ? ' error' : 'error')
您想要操作员的工作h.className
,最好是具体了。结果
当然,没有坏处应该来自h.className += ' error'
,但那是另一回事了。
此外,请注意+
优先于三元运算符: JavaScript的运算符优先
其他提示
可以这样想:
<variable> = <expression> ? <true clause> : <false clause>
该语句的执行方式基本上如下:
- 做
<expression>
评估为 true,还是评估为 false? - 如果
<expression>
评估为 true,则值<true clause>
被分配给<variable>
,<false clause>
被忽略,并执行下一条语句。 - 如果
<expression>
评估结果为 false,则<true clause>
被忽略并且值<false clause>
被分配给<variable>
.
在这种语言和其他语言中使用三元运算符要认识到的重要一点是,无论代码在 <expression>
评估时应该产生布尔结果:无论真假。
在您的示例中,将我的解释中的“分配给”替换为“添加到”,或者对于您正在使用的速记算术(如果有)进行类似操作。
在+=
你想要做什么,但在它的右手三元语句时,它会检查h.className
是falsey,这将是,如果它是不确定的。如果它的truthy(即,如果一个类名称已经指定),然后加入用空间误差(即添加的新类),否则它的加入而不的空间。
的代码可以按照你的建议重写,但你需要指定h.className
是用于感实性对比,而不是使用它的实际价值,在三元运算符,所以一定要确保你不费心值中的同时做你三元操作的级联:
h.className = h.className + (h.className ? ' error' : 'error');
=
操作者的右手侧被从左向右计算。所以,
g.className = h.className + h.className ? ' error' : 'error';`
等同于
h.className = (h.className + h.className) ? ' error' : 'error';
要等同于
h.className += h.className ? ' error' : 'error';
你必须在括号分开三元语句
h.className = h.className + (h.className ? ' error' : 'error');
if (h.className) {
h.className = h.className + ' error';
} else {
h.className = h.className + 'error';
}
应该是等效的:
h.className += h.className ? ' error' : 'error';
我知道这是一个非常古老的问题,但我不是100%满意,任何的答案,因为他们都显得不完整的。所以在这里我们从第一校长又来了:
用户的总体目标:
总结代码:“我想,如果有已经在字符串中的类名的error
类的名字与一家领先的空间添加到字符串,可以选择” 的
简单的解决方案
作为了Kobi指出,5年前,其在类名领先的空间不会引起任何已知的浏览器的任何问题,所以在最短的正确的解决方案实际上是:
h.className += ' error';
这本来应该是的实际的答案应用于的实际问题的。
是因为它可能,该问的问题是...
1)为什么这项工作?
h.className += h.className ? ' error' : 'error'
该条件/三元运算符作品等的if语句,其true
或false
路径的变量分配的结果。
使代码工作,因为它简单地评价为:
if (h.className IS NOT null AND IS NOT undefined AND IS NOT '')
h.className += ' error'
else
h.className += 'error'
2),以及为什么这样做突破?
h.className = h.className + h.className ? ' error' : 'error'
在问题国家“给出了一个[n]的错误在我的控制台”,这可能会误导你以为代码的不起作用的。其实下面的代码并运行,没有的错误的,但它只是返回“错误”,如果该字符串的不是的空,如果字符串的是“错误” 的清空等的不符合要求的
这代码总是导致仅包含' error'
或'error'
,因为它的计算结果为这个伪代码的字符串:
if ((h.className + h.className) IS NOT null AND IS NOT undefined AND IS NOT '')
h.className = ' error'
else
h.className = 'error'
这样做的原因是,加法运算符(+
到公共民间)具有较高的“优先级”(6)大于条件/三元运算符(15)。 我知道数字出现向后
优先级简单地意味着,在操作者语言的每一种类型在一个特定的预定义的次序进行评估(不只是左到右)。
参考:的Javascript运算符优先
如何改变计算顺序:
现在我们知道失败的原因,你需要知道如何使它发挥作用。
一些其他的答案谈论的更改优先级的,但是的你不能的。优先级是硬连接到的语言。这仅仅是一套固定的规则......但是,你可以改变的评估顺序 ...
在我们的工具箱中的工具,它可以改变评估顺序是分组操作者(又名括号)。它通过确保在括号内的表达式进行求值执行此操作的前括号外的操作。这就是他们做的,但这就足够了。
支架简单地工作,因为他们(分组运算符)具有比所有其他运营商的优先级更高的( “现在有一个电平0”)。
通过简单地添加括号你的改变评估顺序以确保条件测试首先进行,简单的字符串连接之前:
h.className = h.className + (h.className ? ' error' : 'error')
现在我将离开这个答案的人之间生锈看不见的:)的
我想选择韦恩的解释:
<variable> = <expression> ? <true clause> : <false clause>
让我们考虑这两种情况:
case 1:
h.className += h.className ? 'true' : 'false'
- 赋值运算符工作正常并且附加值
- 第一次运行时,o/p:错误的
- 第二次。输出:falsetrue——值不断追加
案例2:h.className = h.className + h.className ?'真的' :'错误的'
- 结果与情况1不同
- 第一次运行时,o/p:错误的
- 第二次。输出:false -- 值不会继续追加
explanation
在上面的代码中,情况 1 工作正常
而case2:
h.className = h.className + h.className ? 'true' : 'false'
is executed as
h.className = (h.className + h.className) ? 'true' : 'false'
h.className + h.className
=> 被视为三元运算符的表达式,因为三元运算符具有更高的优先级。所以,三元表达式的结果总是被赋值
您需要使用括号来定义优先级
您需要在括号的帮助下定义要考虑的评估顺序,以使案例 2 与案例 1 一样工作
h.className = h.className + (h.className ? ' error' : 'error')