Приоритет оператора с помощью оператора Javascript Ternary

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

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

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

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

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

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

Ответ 1

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

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

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

Ответ 2

Подумайте об этом так:

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

Способ выполнения оператора в основном выглядит следующим образом:

  • Оценивает ли значение <expression> значение true, или он вычисляется как false?
  • Если <expression> имеет значение true, то значение <true clause> присваивается <variable>, <false clause> игнорируется, а следующий оператор выполняется.
  • Если <expression> получает значение false, то <true clause> игнорируется, а значение <false clause> присваивается <variable>.

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

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

Ответ 3

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

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

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

Ответ 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');

Ответ 5

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

должен быть эквивалентен:

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

Ответ 6

Я хотел бы выбрать объяснение wayne:

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

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

case 1:
h.className += h.className ? 'true' : 'false'     
  • Оператор присваивания
  • работает отлично, а значение добавляется
  • при запуске в первый раз, o/p: false
  • 2-й раз. o/p: falsetrue - значения сохраняются.

Вариант 2: h.className = h.className + h.className? 'true': 'false'

  • результат не такой же, как в случае 1
  • при запуске в первый раз, o/p: false
  • 2-й раз. 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') 

Ответ 7

Я знаю, что это очень старый вопрос, но я не на 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')

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