Приоритет оператора с тернарным оператором Javascript
Я не могу показаться, чтобы обернуть мою голову вокруг первой части этого кода ( += ) в сочетании с тернарным оператором.
h.className += h.className ? ' error' : 'error'
Я думаю, что этот код работает это следующим образом:
h.className = h.className + h.className ? ' error' : 'error'
но это не правильно, потому что дает ошибку в консоли.
Итак, мой вопрос: как я должен правильно интерпретировать этот код?
7 ответов:
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>должен давать логический результат при вычислении: либо 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')