Javascript三元运算符的运算符优先级

Javascript三元运算符的运算符优先级,javascript,variable-assignment,conditional-operator,operator-precedence,compound-assignment,Javascript,Variable Assignment,Conditional Operator,Operator Precedence,Compound Assignment,我似乎无法将这段代码的第一部分(+=)与三元运算符结合起来 h.className += h.className ? ' error' : 'error' 我认为该代码的工作方式如下: h.className = h.className + h.className ? ' error' : 'error' 但这是不正确的,因为这在我的控制台中给出了一个错误 所以我的问题是我应该如何正确地解释这段代码 h.className = h.className + (h.className ? ' e

我似乎无法将这段代码的第一部分(+=)与三元运算符结合起来

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”
不会造成任何伤害,但那是另一回事


另外,请注意,
+
优先于三元运算符:

运算符的右侧从左到右求值。所以

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');
相当于

h.className = (h.className + h.className) ? ' error' : 'error';
h.className += h.className ? ' error' : 'error';
h.className = h.className + (h.className ? ' error' : 'error');
必须在括号中分隔三元语句

h.className = h.className + (h.className ? ' error' : 'error');

+=
执行您想要的操作,但是在它右边的三元语句中,它检查
h.className
是否为false,如果未定义,则为false。如果它是真实的(即,如果已经指定了类名),则会使用空格添加错误(即,添加新类),否则将不使用空格添加错误

代码可以按照您的建议进行重写,但您需要指定
h.className
用于三元运算符中的真实性比较,而不是使用其实际值,因此请确保在执行三元运算的同时不必担心值的串联:

应相当于:

h.className += h.className ? ' error' : 'error';
这样想:

<variable> = <expression> ? <true clause> : <false clause>
=?:
语句的执行方式基本如下:

  • 的计算结果是true还是false
  • 如果
    的计算结果为true,则将
    的值分配给
    将被忽略,并执行下一条语句
  • 如果
    的计算结果为false,则忽略
    ,并将
    的值分配给
  • 在这种语言和其他语言中,使用三元运算符需要意识到的重要一点是,
    中的任何代码在求值时都应该产生布尔结果:true或false


    在您的示例中,请将我的解释中的“分配给”替换为“添加到”,或对您正在使用的任何速记算法(如果有)进行类似操作。

    我想选择wayne的解释:

    <variable> = <expression> ? <true clause> : <false clause>
    
    • 赋值运算符工作正常,并追加值
    • 第一次运行时,o/p:false
    • 第二次。o/p:falsetrue--值不断追加
    案例2: h、 className=h.className+h.className?“true':'false'

    • 结果与案例1不同
    • 第一次运行时,o/p:false
    • 第二次。o/p:false--值不会一直追加
    说明

    在上面的代码中,情况1可以正常工作

    鉴于 案例2:

    h.className+h.className
    =>被视为三元运算符的表达式,因为三元运算符具有更高的优先级。所以,三元表达式的结果总是赋值的

    您需要使用括号来定义优先级

    您需要在括号的帮助下定义要考虑的评估顺序,以便案例2与案例1一样工作

    h.className = h.className + (h.className ? ' error' : 'error') 
    

    我知道这是一个非常古老的问题,但我对任何答案都不是100%满意,因为它们似乎都不完整。我们再来看第一个原则:

    用户的总体目标: 总结代码:“我希望在字符串中添加
    错误
    类名,如果字符串中已经有类名,则可以选择使用前导空格。”

    最简解 正如Kobi所指出的,5年前,在类名中使用前导空格不会对任何已知浏览器造成任何问题,因此最短的正确解决方案实际上是:

    h.className += ' error';
    
    这应该是实际问题的实际答案


    尽管如此,提出的问题是

    1) 为什么会这样? 条件/三元运算符的工作方式类似于if语句,它将其
    true
    false
    路径的结果分配给变量

    因此,代码之所以有效,是因为它的计算方法很简单:

    if (h.className IS NOT null AND IS NOT undefined AND IS NOT '') 
        h.className += ' error'
    else
        h.className += 'error'
    
    2) 为什么会破裂? 该问题指出“在我的控制台中出现[n]个错误”,这可能会误导您认为代码不起作用。事实上,下面的代码确实运行,没有错误,但如果字符串不为空,它只返回'error',如果字符串为空,则返回'error',因此不符合要求

    该代码总是生成一个只包含
    'error'
    'error'
    的字符串,因为它的计算结果是此伪代码:

    if ((h.className + h.className) IS NOT null AND IS NOT undefined AND IS NOT '')
        h.className = ' error'
    else
        h.className = 'error'
    
    这是因为加法运算符(
    +
    到普通运算符)比条件/三元运算符(15)具有更高的“优先级”(6)。我知道数字是倒过来的

    优先级仅仅意味着一种语言中的每种类型的运算符都按照特定的预定义顺序(而不仅仅是从左到右)进行计算

    参考: 如何更改评估顺序: 现在我们知道它为什么失败了,你需要知道如何让它工作

    其他一些答案谈到改变优先级,但你不能。优先权是语言的固有属性。这只是一套固定的规则。。。但是,您可以更改评估顺序

    工具箱中可以更改求值顺序的工具是分组运算符(又名括号)。它通过确保在括号外的操作之前对括号内的表达式求值来实现这一点。这就是他们所做的,但这已经足够了

    方括号之所以有效,是因为它们(分组运算符)的优先级高于所有其他运算符(“现在有一个级别0”)

    通过简单地添加括号,您可以更改求值顺序以确保条件
    h.className = h.className + h.className ? ' error' : 'error'
    
    if ((h.className + h.className) IS NOT null AND IS NOT undefined AND IS NOT '')
        h.className = ' error'
    else
        h.className = 'error'
    
    h.className = h.className + (h.className ? ' error' : 'error')