Вопрос по operator-precedence, conditional-operator, compound-assignment, variable-assignment, javascript – Приоритет оператора с тернарным оператором Javascript

116

Кажется, я не могу обернуть голову вокруг первой части этого кода (+ =) в сочетании с троичным оператором.

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

Я думаю, что этот код работает следующим образом:

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

Но это нене правильно, потому что это дает ошибку в моей консоли.

Итак, мой вопрос, как я должен правильно интерпретировать этот код?

Ваш Ответ

7   ответов
1

что это очень старый вопрос, но я не на 100% доволен ни одним из ответов, поскольку все они кажутся неполными. Итак, здесь мы снова идем от первых принципов:

Пользователь'Общая цель:

Резюмируя код: «Я хочу добавитьerror имя класса в строку, необязательно с начальным пробелом, если в строке уже есть имена классов. "

Самое простое решение

Как отметил Коби, 5 лет назад наличие лидирующего пробела в именах классов не вызывало проблем с любыми известными браузерами, поэтому самое короткое правильное решение на самом деле было бы:

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' или же'error' потому что он оценивает этот псевдокод:

if ((h.className + h.className) IS NOT null AND IS NOT undefined AND IS NOT '')
    h.className = ' error'
else
    h.className = 'error'

Причина этого заключается в том, что оператор сложения (+ к простому народу) имеет высшеестаршинство» (6), чем условный / троичный оператор (15)., что цифры появляются в обратном направлении

старшинство просто означает, что каждый тип оператора в языке оценивается в определенном предопределенном порядке (а не только слева направо).

Ссылка:Приоритет оператора JavascriptКак изменить порядок оценки:

Теперь мы знаем, почему это не помогает, вам нужно знать, как заставить это работать.

Некоторые другие ответы говорят оизменение приоритета, ноты не можешь, Приоритет запрограммирован в язык. Это просто фиксированный набор правил ... Однако вы можете изменитьпорядок оценки...

Инструмент в нашем наборе инструментов, который можетизменить порядок оценки является оператором группировки (он же скобки). Это достигается путем проверки выражений в скобкахдо операции вне скобок. Тот'Все, что они делают, но этодостаточно.

Скобки работают просто потому, что они (операторы группировки) имеютболее высокий приоритет, чем у всех других операторов ("там сейчас уровень 0 ").

Просто добавив скобки, выизменить порядок оценки чтобы убедиться, что сначала выполняется условный тест, перед простой конкатенацией строк:

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

Теперь я оставлю этот ответ на ржавчину невидимым среди других :)

3
if (h.className) {
    h.className = h.className + ' error';
} else {
    h.className = h.className + 'error';
}

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

h.classNameЛучше будь конкретнее.

Конечно, никакого вреда не должно бытьh.className += ' error', но это'это другое дело.

Также обратите внимание, что+ имеет приоритет над троичным оператором:Приоритет оператора JavaScript

@JMTyler - Этоэто именно то, что я указывал - если этовсе сделано только для того, чтобы сохранить пространство с самого начала, я неэто того не стоит. (крайний случай включает точные селекторы jQuery или XPath). В любом случае, спасибо. Kobi
@ Коби +1 только за предупреждение о приоритете оператора! Ed Chapel
+1 за избиение до правильного ответа David Hedlund
Я думаю, что следует отметить, что в то время какh.className += ' error', он также оставляет пустое место в начале строки, если она была изначально пустой. Я полагаю, что смысл троичной операции состоит в том, чтобы создать чистую на вид строку. JMTyler
129

<variable> = <expression> ? <true clause=""> : <false clause="">
</false></true></expression></variable>

Способ выполнения инструкции в основном следующий:

Есть ли оценивать как истинное, или оно оценивается как ложное?Если оценивается как истина, то значение назначен, игнорируется, и следующий оператор выполняется.Если оценивается как ложное, то игнорируется и значение назначен на.

С этим троичным оператором на этом и других языках важно понимать, что любой код должен давать логический результат при оценке: либо true, либо false.

В случае вашего примера заменитеназначен на " в моем объяснении с "Добавлено в"или аналогичный для любой сокращенной арифметики, которую вы используете, если таковой имеется.

Обратите внимание, что еслиидеально комментарий уместен :) Он пропускает любое объяснениеЗачем левые выражения "сгруппированы вместе во-первых (т.е. потому что+ имеет больший приоритет, чем условный / троичный оператор (на самом деле условный операторпочти всегда последний оценивается в любом выражении). Gone Coding
+1 идеальное объяснение jyoseph
4

Правая сторона= Оператор оценивается слева направо. Так,

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

+= делает то, что вы хотите, но в троичном выражении справа от него, он проверяет,h.className это фальси, что было бы, если бы он был неопределенным. Если оно'с правдой (т.е. если имя класса уже указано), то ошибка добавляется с пробелом (т.е. добавлениеновый класс), иначеs добавлено без пробела.

Код может быть переписан, как вы предлагаете, но вы должны указать, чтоh.className должен использоваться для сравнения правдивости, а не для использования его фактического значения в троичном операторе, поэтому убедитесь, что вы неt беспокоиться о конкатенации значений одновременно с выполнением троичной операции:

h.className = h.className + (h.className ? ' error' : 'error');
Фэлси, а? ;) Justin Johnson
Ну, да,undefined неложный Это'просто так, как если бы это было David Hedlund
1

<variable> = <expression> ? <true clause=""> : <false clause="">
</false></true></expression></variable>

Давайте рассмотрим оба случая:

case 1:
h.className += h.className ? 'true' : 'false'     
оператор присваивания работает нормально и значение добавляетсяпри первом запуске o / p: false2-й раз. o / p: falsetrue - значения продолжают добавляться

case2: h.className = h.className + h.className? 'правда' : 'ложный'

результат не такой, как в случае 1при первом запуске o / p: false2-й раз. 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') 
@TrueBlueAussie Я принимаю это. я ценю ваше намерение читать +1 Angelin Nadar
Терминология здесь не совсем верна. Приоритетность присуща языку, вы неопределить это, Вы вместо этого определяетепорядок оценки вводя скобки (которые имеют более высокий приоритет, чем все другие операторы). Gone Coding

Похожие вопросы