web-dev-qa-db-ja.com

Javascript Ternary演算子を使用した演算子の優先順位

三項演算子と組み合わせて、このコードの最初の部分(+ =)に頭を巻き付けることはできません。

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

このコードが機能すると思う方法は次のとおりです:

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

しかし、それは私のコンソールにエラーを与えるため、正しくありません。

だから私の質問は、このコードを正しくインターペットする必要がありますか?

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

演算子をh.classNameで動作させたい場合、具体的に指定してください。
もちろん、h.className += ' error'による害はありませんが、それは別の問題です。

また、+は三項演算子よりも優先されることに注意してください。 JavaScript Operator Precedence

141
Kobi

このように考えてください:

<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のブール結果を生成することです。

あなたの例の場合、私の説明の「に割り当てられた」を「追加された」に置き換えます。

129
Wayne Koorts

+=は必要な処理を行いますが、右側の3項ステートメントでは、h.classNameが偽であるかどうかをチェックします。真実である場合(つまり、クラス名が既に指定されている場合)、エラーがスペースと共に追加されます(つまり、newクラスを追加します)、そうでない場合は、スペースなしで追加されます。

コードは提案どおりに書き直すことができますが、h.classNameを三項演算子で実際の値を使用するのではなく、真実性の比較に使用するように指定する必要があります。三項演算を行うと同時に値を連結します。

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

=演算子の右側は、左から右に評価されます。そう、

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');
4
Justin Johnson
if (h.className) {
    h.className = h.className + ' error';
} else {
    h.className = h.className + 'error';
}

以下と同等である必要があります:

h.className += h.className ? ' error' : 'error';
3
Darin Dimitrov

ウェインの説明を選びたい:

<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 =>三項演算子の優先順位が高いため、三項演算子の式と見なされます。そのため、常に三項式の結果が割り当てられます

括弧を使用して優先順位を定義する必要があります

ケース2がケース1として機能するように、括弧の助けを借りて評価する評価の順序を定義する必要があります

h.className = h.className + (h.className ? ' error' : 'error') 
1
Angelin Nadar

これは非常に古い質問であることは知っていますが、すべての回答が不完全であるように見えるため、どの回答にも100%満足していません。そこで、ここで最初のプリンシパルから再び行きます。

ユーザーの全体的な目的:

コードの要約:"errorクラス名を文字列に追加します。文字列に既にクラス名が存在する場合、オプションで先頭にスペースを追加します。"

最も簡単なソリューション

5年前にKobiが指摘したように、クラス名の先頭にスペースがあっても、既知のブラウザーで問題は発生しません。したがって、実際の最短の解決策は次のとおりです。

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なしで実行されますが、文字列was notの場合は単に 'error'を返し、文字列wasの場合は '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)を持っているためです。 数字が逆向きに表示されることを知っています

Precedenceは、言語の各タイプの演算子が特定の事前定義された順序で評価されることを意味します(左から右だけではありません)。

リファレンス: Javascript Operator Precedence

評価の順序を変更する方法:

これで失敗する理由がわかりました。動作させる方法を知る必要があります。

他のいくつかの答えは優先順位の変更ですが、することはできませんです。優先順位は言語に組み込まれています。これはルールの固定セットです...ただし、評価の順序 ...を変更できます。

評価の順序を変更できるツールボックスのツールは、グループ化演算子(ブラケット)です。これは、括弧内の式が評価されることを保証することにより、これを行いますbefore括弧外の操作。彼らはそれですべてですが、それで十分です。

ブラケットは、単純に(グループ化演算子)が他のすべての演算子よりも優先順位が高い(「レベル0になりました」)であるため機能します。

単純にブラケットを追加することで、単純な文字列の連結の前に最初に条件付きテストが実行されるように、評価の順序を変更します。

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

これからは、この答えをRustに残して、他では見られない:)

1
Gone Coding