簡體   English   中英

運算符優先級與Javascript三元運算符

[英]Operator precedence with Javascript Ternary operator

我似乎無法將這個代碼的第一部分(+ =)與三元運算符結合起來。

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。

在你的例子的情況下,在我的解釋中用“添加到”替換“已分配給”,或者對於你使用的任何簡寫算法都是類似的,如果有的話。

+=做你想要的,但是在它右邊的三元語句中,它會檢查h.className是否為falsey,如果它是未定義的話。 如果它是真實的(即,如果已經指定了類名),則添加帶有空格的錯誤(即添加類),否則添加沒有空格的錯誤。

代碼可以按照你的建議重寫,但你需要指定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';

我知道這是一個非常古老的問題,但我對任何答案都不是百分之百滿意,因為它們似乎都不完整。 所以這里我們再次從第一個校長:

用戶的總體目標:

總結代碼: “我希望在字符串中添加一個error類名,如果字符串中已有類名,則可選擇使用前導空格。”

最簡單的解決方案

正如Kobi在5年前指出的那樣,在類名中擁有領先的空間不會對任何已知的瀏覽器造成任何問題,因此最短的正確解決方案實際上是:

h.className += ' error';

這應該是實際問題實際答案


盡管如此,提出的問題是......

1)為什么這樣做?

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

條件/三元運算符的工作方式類似於if語句,它將其truefalse路徑的結果分配給變量。

所以代碼工作,因為它被簡單地評估為:

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'

其原因是加法運算符( +對普通民眾)具有比條件/三元運算符(15)更高的“優先級”(6)。 我知道這些數字是倒退的

優先級僅意味着語言中的每種類型的運算符都以特定的預定義順序(而不僅僅是從左到右)進行評估。

參考: Javascript運算符優先級

如何更改評估順序:

現在我們知道它失敗的原因,你需要知道它是如何工作的。

其他一些答案談論改變優先權 ,但你不能 優先權與語言緊密相連。 這只是一套固定的規則......但是,您可以更改評估順序 ......

我們的工具箱中可以更改評估順序的工具是分組操作符(也就是括號)。 它通過確保在括號外的操作之前評估括號中的表達式來實現此目的。 這就是他們所做的一切,但這就足夠了。

括號的工作原理很簡單,因為它們(分組運算符)的優先級高於所有其他運算符 (“現在有0級”)。

通過簡單地添加括號,您可以更改評估順序,以確保在簡單字符串連接之前首先執行條件測試:

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

我現在將這個答案留給其他人看不見的生銹:)

我想選擇Wayne的解釋:

<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工作正常

而案例2:

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') 

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM