Приоритет оператора с тернарным оператором Javascript


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

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

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

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

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

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

7 115

7 ответов:

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.

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

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

код может быть переписан как вы предлагаете, но нужно указать, что 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';

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

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

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

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

рассмотрим оба случая:

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

случай 2: ч. имякласса = сек.класса + Н.имя_класса ? 'true':'false'

  • результат не то же, что и в случае 1
  • когда запускается в первый раз, o/p: false
  • 2-й раз. o / p: false -- values не продолжает добавлять

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