Приоритет: логический или тернарный оператор

Примите во внимание следующее:
(EDIT: я немного изменил функцию, убрав использование фигурных скобок с тернарным оператором)

function someFunction(start,end,step){
  var start = start || 1,
      end = end || 100,
      boolEndBigger = (start < end);   // define Boolean here
      step = step || boolEndBigger ? 1:-1;
  console.log(step); 
}

someFunction()
// step isn't defined so expect (1<10) ? 1:-1  to evaluate to 1

someFunction(1,10)  
// again step isn't defined so expect to log 1 as before

Проблема:

someFunction(1,10,2) 
//step IS defined, shortcut logical OR || should kick in, 
//step should return 2 BUT it returns 1

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

function range(start,end,step){
  var start = start || 1,
      end = end || 100,
      step = step || ((start < end) ? 1:-1);
  console.log(step); 
}

Вопрос: Почему в этом случае оператор || не работает?

Я знаю, что логическое ИЛИ имеет самый низкий приоритет среди бинарных логических условных операторов, но думал, что он имеет более высокий приоритет, чем условный тернарный оператор?

Я неправильно понимаю документацию MDN по приоритету операторов?


person Pineda    schedule 03.02.2017    source источник
comment
более высокий приоритет означает, что ваш код оценивается как (step || (start < end)) ? 1 : -1   -  person Niet the Dark Absol    schedule 03.02.2017
comment
«Более высокий приоритет» означает, что || оценивается первым, т. е. step || (start < end) оценивается первым.   -  person Sebastian Simon    schedule 03.02.2017
comment
@NiettheDarkAbsol: это будет означать, что тройка имеет больший приоритет, верно? Документы MDN говорят об обратном...   -  person Pineda    schedule 03.02.2017
comment
@Xufox: если бы это было так, то третий вызов вернул бы 2. Это не ...   -  person Pineda    schedule 03.02.2017
comment
@Pineda Нет… step || (start < end) ? 1 : -1 оценивается как step ? 1 : -1, потому что || оценивается первым, а step соответствует действительности. Затем step ? 1 : -1 оценивается как 1, потому что step соответствует действительности.   -  person Sebastian Simon    schedule 03.02.2017
comment
Я отредактировал свой вопрос, чтобы уточнить, о чем я спрашиваю...   -  person Pineda    schedule 03.02.2017
comment
Но вы не читаете наши комментарии.   -  person Niet the Dark Absol    schedule 03.02.2017
comment
@NiettheDarkAbsol: Я понял, я не задал главный вопрос: почему оператор || не выполняет ярлык, см. ответ @lonesomeday. Я отредактировал это сейчас, чтобы уточнить.   -  person Pineda    schedule 03.02.2017


Ответы (2)


Да, оператор || имеет более высокий приоритет, чем условный оператор ?:. Это означает, что он выполняется первым. Со страницы вы ссылка :

Приоритет оператора определяет порядок, в котором оцениваются операторы. Операторы с более высоким приоритетом оцениваются первыми.

Давайте посмотрим на все операции здесь:

step = step || (start < end) ? 1:-1;

Оператором с наивысшим приоритетом является операция группировки (). Здесь это приводит к false:

step = step || false ? 1 : -1;

Следующим по приоритету является логический оператор ИЛИ. step соответствует действительности, поэтому получается step.

step = step ? 1 : -1;

Теперь мы делаем тернарную операцию, которая осталась единственной. Опять же, step соответствует действительности, поэтому выполняется первый из вариантов.

step = 1;
person lonesomeday    schedule 03.02.2017
comment
Я понял. Чего я не понимаю, так это почему || не сокращается, когда в этом случае левое условие истинно? - person Pineda; 03.02.2017
comment
@ Пинеда Так и есть. Его левый операнд — step, а правый операнд — false. false никогда не выполняется. - person lonesomeday; 03.02.2017
comment
step = step || false ? 1 : -1; почему тогда здесь казнят false ? 1:-1, разве это не эквивалентно step = step || (false ? 1 : -1); - person Pineda; 03.02.2017
comment
ах, подождите... Кажется, я понял, мое предположение было таково: false ? 1 : -1 считается вторым условием ||, а не просто ложным - person Pineda; 03.02.2017
comment
@Pineda Да, правая часть до следующего оператора является операндом, а не все справа. Подумайте, как выполняется 5 + 2 * 3 + 4. * имеет более высокий приоритет, чем +, поэтому 2*3 выполняется первым. - person lonesomeday; 03.02.2017
comment
Спасибо. Я понимаю. Я исправил свой вопрос, чтобы удалить скобки. С удаленными скобками из тернарного оператора поток приоритета изменяется, но я все еще получаю сообщение об ошибке - person Pineda; 03.02.2017
comment
О, подожди. Понятно, до следующего оператора. Достаточно справедливо и большое спасибо! - person Pineda; 03.02.2017

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

Давайте посмотрим несколько сценариев, как он преобразуется в другой тип.

пример 1.

Оператор if() ожидает логическое значение, поэтому все, что вы определяете в скобках, будет преобразовано в логическое значение.

Значения JavaScript часто называют «истинными» или «ложными» в зависимости от того, каким будет результат такого преобразования (т. е. истинным или ложным).

Помните, является ли значение истинным, если не известно, что оно ложное.

К счастью, фальшивых всего шесть -

  1. неверно (конечно!)
  2. неопределенный
  3. нулевой
  4. 0 (цифровой ноль)
  5. "" (пустой строки)
  6. NaN (не число)

пример 2.

вар х = зоопарк || звезда ;

Если зоопарк оценивается как истина, то возвращается значение зоопарка, в противном случае возвращается значение звезды

пример 3.

var str = '1' || '2';

«1» не является ложным, поэтому будет возвращен результат «1»: str = «1»;

пример 4.

var str = '1' || (true) ? '2' : '3';

во-первых, приоритет оператора ||(логическое ИЛИ) больше, чем оператор ?(условный)

поэтому first ( '1' || (true)) будет оцениваться первым

«1» не является ложным, поэтому будет возвращено «1»

Промежуточный результат: str = '1' ?' 2' : "3"

«1» не соответствует действительности, поэтому будет возвращено «2»

Окончательный результат: ул = '2'

пример 5.

var str = '1' || (false) ? '2' : '3';

во-первых, приоритет оператора ||(логическое ИЛИ) больше, чем оператор ?(условный)

поэтому first ( '1' || (false) ) будет оцениваться первым

«1» не является ложным, поэтому будет возвращено «1»

Промежуточный результат: str = '1' ?' 2' : "3"

«1» не соответствует действительности, поэтому будет возвращено «2»

Окончательный результат: ул = '2'

Теперь будет очень легко разобраться в вашем сценарии :)

person dhaker    schedule 18.06.2018