14.05.2020, 16:56
|
|
Профессор
|
|
Регистрация: 20.12.2009
Сообщений: 1,714
|
|
Как работают бинарные логические операторы && и || в JavaScript?
Вот краткий пересказ своими словами из спецификации ECMAScript 2020 о том, как работают логические операторы.
ToBoolean ( аргумент )
Абстрактная операция ToBoolean принимает аргумент. Она преобразует аргумент в значение типа Boolean согласно следующей таблице:
Код:
|
┌───────────────┬──────────────────────────────────────────────┐
│ Тип аргумента │ Результат │
├───────────────┼──────────────────────────────────────────────┤
│ Undefined │ возвратить false │
├───────────────┼──────────────────────────────────────────────┤
│ Null │ возвратить false │
├───────────────┼──────────────────────────────────────────────┤
│ Boolean │ возвратить аргумент │
├───────────────┼──────────────────────────────────────────────┤
│ Number │ если аргумент равен +0, -0 или NaN, │
│ │ то возвратить false, иначе возвратить true │
├───────────────┼──────────────────────────────────────────────┤
│ String │ если аргумент является пустой строкой │
│ │ (её длина равна нулю), то возвратить false, │
│ │ иначе возвратить true │
├───────────────┼──────────────────────────────────────────────┤
│ Symbol │ возвратить true │
├───────────────┼──────────────────────────────────────────────┤
│ BigInt │ если аргумент равен 0n, то возвратить false, │
│ │ иначе возвратить true │
├───────────────┼──────────────────────────────────────────────┤
│ Object │ возвратить true │
└───────────────┴──────────────────────────────────────────────┘ |
Когда вычисляется A && B, то происходит следующее... - Если ToBoolean( A ) возвращает false, то вернуть A
- иначе вернуть B
Когда вычисляется A || B, то происходит следующее... - Если ToBoolean( A ) возвращает true, то вернуть A
- иначе вернуть B
|
|
14.05.2020, 17:36
|
Аспирант
|
|
Регистрация: 15.02.2014
Сообщений: 32
|
|
Когда вычисляется A || B, то происходит следующее...
Если ToBoolean( A ) возвращает true, то вернуть A
иначе вернуть B
console.log((a || c)) //undefined
Если результат 'с' которое undefined - false какого он возвращает undefined
Согласно вашей же табличке результат вычисления 'c' в булевом выражении - false и общий результат должен быть false, а не undefined
|
|
14.05.2020, 17:57
|
|
Профессор
|
|
Регистрация: 20.12.2009
Сообщений: 1,714
|
|
Сообщение от andypop
|
Согласно вашей же табличке результат вычисления 'c' в булевом выражении - false и общий результат должен быть false, а не undefined
|
А где это вы увидели, что ToBoolean возвращает напрямую в качестве окончательного результата своё значение?
var a=false
var b=true
var c=undefined
console.log((a || c)) //undefined
console.log((b || c))//true
Я так понимаю (судя по коду выше), a || c у вас означает false || undefined . Смотрим...
Когда вычисляется A || B, то происходит следующее... - Если ToBoolean( A ) возвращает true, то вернуть A
- иначе вернуть B
Подстанавливаем ваше выражение, получается...
Когда вычисляется (A = false) || (B = undefined), то происходит следующее... - Если ToBoolean( A = false ) возвращает true (а согласно таблице ToBoolean( A = false ) возвращает false), то вернуть A (поскольку условие не выполняется, смотрим далее)
- иначе вернуть B (согласно подстановке, B было undefined, значит его и нужно вернуть)
Следовательно false || undefined === undefined
|
|
14.05.2020, 18:13
|
Аспирант
|
|
Регистрация: 15.02.2014
Сообщений: 32
|
|
Ну т.е. для булевых выражений работают правила, а не табличка, согласно которой если аргумент undefined ,то результат false
|
|
14.05.2020, 18:39
|
Аспирант
|
|
Регистрация: 15.02.2014
Сообщений: 32
|
|
Я вот и хотел, чтобы объяснили эту тонкость, а для булевых значений я в курсе. Речь идет об интерпретаторе, когда тип аргументов еще не известен. Можно использовать и правила js для toBoolean, но я против таких абстракций. фактически незначение undefined приравнено к значению. Хотя по идее если от значения undefined зависит результат булевой операции нужно возвращать undefined. Понятно, что правила сделаны в угоду синтаксису. Но ...
|
|
15.05.2020, 08:10
|
|
Профессор
|
|
Регистрация: 03.02.2020
Сообщений: 2,750
|
|
Сообщение от andypop
|
Нельзя поломать то, что уже поломано. И именно в булевых выражениях.
1+ undefined и undefined+1 даст одно и то же NaN. С точки зрения логики ассоциативность в языке не должна влиять на результат булевых выражений . Так что не чушь.
|
В JS нет понятия ассоциативности. Это не математика.
Все операции выполняются так, как они записаны, с учетом лево или правосторонности.
Операция + ни грамма не ассоциативная.
1+ "0" и "0" + 1
Операции && и || не булевы, а логические. Так они названы в спецификации.
Булевые операции подразумевали бы, что их операнды должны иметь тип boolean и выдавать такой же результат.
Сообщение от andypop
|
Как допустили, что не булево незначение участвует и влияет причем весьма странным образом в булевых операциях?
|
Это не незначение, а именно значение.
В JS есть тип undefined (такой же как Number, String, Boolean) с единственным значением undefined
|
|
15.05.2020, 08:53
|
Профессор
|
|
Регистрация: 14.01.2015
Сообщений: 12,989
|
|
Сообщение от voraa
|
В JS нет понятия ассоциативности.
|
В контексте приоритета операторов или?
|
|
15.05.2020, 09:26
|
|
Профессор
|
|
Регистрация: 03.02.2020
Сообщений: 2,750
|
|
Сообщение от laimas
|
В контексте приоритета операторов или?
|
Что такое приоритет?
В спецификации нет такого понятия.
|
|
15.05.2020, 09:57
|
Профессор
|
|
Регистрация: 14.01.2015
Сообщений: 12,989
|
|
|
|
15.05.2020, 10:32
|
|
Профессор
|
|
Регистрация: 03.02.2020
Сообщений: 2,750
|
|
mdn хорошая вещь.
Но это не спецификация, а только ее трактовка. Иногда не совсем полная.
|
|
|
|