运算符优先与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> 

语句执行的方式基本如下:

  1. <expression>评估为true,还是评估为false?
  2. 如果<expression>计算结果为true,则将<true clause>值赋给<variable> ,将忽略<false clause> ,并执行下一个语句。
  3. 如果<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语句一样工作,将其truefalsepath的结果赋值给一个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')