运算符优先与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>
中的任何代码在计算时都应该产生一个布尔结果:true或者false。
在你的例子的情况下,在我的解释中用“added to”replace“assigned to”,或者使用你所使用的简写algorithm(如果有的话)。
+=
做你想做的事情,但是在它右侧的三元语句中,它检查h.className
是否是falsey,如果它是未定义的,它将会是falsey。 如果是真的(即如果已经指定了一个类名),那么错误就会被添加一个空格(即添加一个新的类),否则就会被添加而没有空格。
代码可以像你所build议的那样被重写,但是你需要指定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';
我知道这是一个非常古老的问题,但我对任何答案都不满意,因为它们看起来都不完整。 所以,我们再次从第一位校长那里了解到:
用户的总体目标是:
总结下面的代码: “我希望给一个string添加一个error
类名,如果string中已经有类名的话,可以select一个前导空格。”
最简单的解决scheme
正如Kobi指出的那样,5年前,在类名中占有领先的空间不会对任何已知的浏览器造成任何问题,所以最短正确的解决scheme实际上是:
h.className += ' error';
这应该是实际问题的实际答案 。
就这样,问的问题是…
1)为什么这个工作?
h.className += h.className ? ' error' : 'error'
条件/三元运算符像if语句一样工作,将其true
或false
path的结果赋值给一个variables。
所以代码工作,因为它被评估为:
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]错误”,这可能会误导您认为代码不起作用 。 实际上,下面的代码没有错误地运行,但是如果string不是空的,它会简单地返回'error',如果string是空的,那么它会返回'error',所以不符合要求 。
该代码总是导致只包含' error'
或'error'
的string,因为它评估为这个伪代码:
if ((h.className + h.className) IS NOT null AND IS NOT undefined AND IS NOT '') h.className = ' error' else h.className = 'error'
其原因是加法运算符( +
对普通民众)具有比有条件/三元运算符(15)更高的“优先级”(6)。 我知道数字出现倒退
优先级仅仅意味着语言中的每种types的操作符都是以特定的预定义顺序(而不仅仅是从左到右)进行评估的。
参考: Javascript运算符优先级
如何改变评估顺序:
现在我们知道为什么它失败了,你需要知道如何使它工作。
其他一些答案提到改变优先顺序 ,但是你不能 。 优先级是硬编码的语言。 这只是一套固定的规则…但是,您可以更改评估顺序 …
我们的工具箱中可以改变评估顺序的工具是分组操作符(aka括号)。 它通过确保在括号外的操作之前评估括号中的expression式来实现这一点。 这就是他们所做的,但这就够了。
括号的工作原理是因为它们(分组操作符) 比所有其他操作符具有更高的优先级 (“现在有0级”)。
通过简单地添加括号,您可以更改评估的顺序,以确保在简单string连接之前首先执行条件testing:
h.className = h.className + (h.className ? ' error' : 'error')
我现在将离开这个答案在别人之间看不见的东西:)
我想selectwayne的解释:
<variable> = <expression> ? <true clause> : <false clause>
让我们考虑这两种情况:
case 1: h.className += h.className ? 'true' : 'false'
- 赋值运算符工作正常,值被附加
- 当第一次运行时,o / p:false
- 第二次 o / p:falsetrue – 值不断追加
case2:h.className = h.className + h.className? '真假'
- 结果与案例1不一样
- 当第一次运行时,o / p:false
- 第二次 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
=>被认为是三元运算符的expression式,因为三元运算符被赋予更高的优先级。 所以,总是三元expression的结果是刚刚分配
您需要使用方括号来定义优先级
您需要在案例2的括号的帮助下定义评估的顺序以作为案例1工作
h.className = h.className + (h.className ? ' error' : 'error')