Приоритет оператора с помощью троичного оператора Javascript
Вопрос
Кажется, я не могу разобраться с первой частью этого кода ( + = ) в сочетании с троичным оператором.
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>
Способ выполнения инструкции в основном заключается в следующем:
- Делает
<expression>
оцените значение true, или оно оценивает значение false? - Если
<expression>
принимает значение true, тогда значение<true clause>
присваивается<variable>
,<false clause>
игнорируется, и выполняется следующий оператор. - Если
<expression>
принимает значение false, затем<true clause>
игнорируется , и значение<false clause>
присваивается<variable>
.
Важная вещь, которую следует осознать с помощью тернарного оператора в этом и других языках, заключается в том, что какой бы код ни был в <expression>
должен выдавать логический результат при вычислении:либо истина, либо ложь.
В случае вашего примера замените "присвоено" в моем объяснении на "добавлено к" или аналогично для любой используемой вами сокращенной арифметики, если таковая имеется.
В +=
делает то, что вы хотите, но в троичном операторе справа от него он проверяет, является ли h.className
является ложным, каковым оно было бы, если бы было неопределенным.Если это правдиво (т.е.если имя класса уже указано), то ошибка добавляется с пробелом (т.е.добавление новое class), в противном случае он добавляется без пробела.
Код можно было бы переписать так, как вы предлагаете, но вам нужно указать, что 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')
Теперь я оставлю этот ответ rust незамеченным среди других :)
Я хотел бы выбрать объяснение Уэйна :
<variable> = <expression> ? <true clause> : <false clause>
Давайте рассмотрим оба случая:
case 1:
h.className += h.className ? 'true' : 'false'
- оператор присваивания работает нормально, и значение добавляется
- при запуске в первый раз, o/p:ложь
- 2-й раз.o/p:falsetrue - значения продолжают добавляться
случай 2:h.className = h.className + h.className ?"верно" :"ложь"
- результат не такой, как в случае 1
- при запуске в первый раз, o/p:ложь
- 2-й раз.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')