Javascript-форум (https://javascript.ru/forum/)
-   Общие вопросы Javascript (https://javascript.ru/forum/misc/)
-   -   true || undefined // true (https://javascript.ru/forum/misc/80242-true-%7C%7C-undefined-true.html)

Malleys 14.05.2020 16:56

Как работают бинарные логические операторы && и || в 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

andypop 14.05.2020 17:36

Когда вычисляется A || B, то происходит следующее...
Если ToBoolean( A ) возвращает true, то вернуть A
иначе вернуть B

console.log((a || c)) //undefined
Если результат 'с' которое undefined - false какого он возвращает undefined
Согласно вашей же табличке результат вычисления 'c' в булевом выражении - false и общий результат должен быть false, а не undefined

Malleys 14.05.2020 17:57

Цитата:

Сообщение от 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

andypop 14.05.2020 18:13

Ну т.е. для булевых выражений работают правила, а не табличка, согласно которой если аргумент undefined ,то результат false

andypop 14.05.2020 18:39

Я вот и хотел, чтобы объяснили эту тонкость, а для булевых значений я в курсе. Речь идет об интерпретаторе, когда тип аргументов еще не известен. Можно использовать и правила js для toBoolean, но я против таких абстракций. фактически незначение undefined приравнено к значению. Хотя по идее если от значения undefined зависит результат булевой операции нужно возвращать undefined. Понятно, что правила сделаны в угоду синтаксису. Но ...

voraa 15.05.2020 08:10

Цитата:

Сообщение от andypop (Сообщение 524201)
Нельзя поломать то, что уже поломано. И именно в булевых выражениях.
1+ undefined и undefined+1 даст одно и то же NaN. С точки зрения логики ассоциативность в языке не должна влиять на результат булевых выражений . Так что не чушь.

В JS нет понятия ассоциативности. Это не математика.
Все операции выполняются так, как они записаны, с учетом лево или правосторонности.
Операция + ни грамма не ассоциативная.
1+ "0" и "0" + 1

Операции && и || не булевы, а логические. Так они названы в спецификации.
Булевые операции подразумевали бы, что их операнды должны иметь тип boolean и выдавать такой же результат.

Цитата:

Сообщение от andypop
Как допустили, что не булево незначение участвует и влияет причем весьма странным образом в булевых операциях?

Это не незначение, а именно значение.
В JS есть тип undefined (такой же как Number, String, Boolean) с единственным значением undefined

laimas 15.05.2020 08:53

Цитата:

Сообщение от voraa
В JS нет понятия ассоциативности.

В контексте приоритета операторов или?

voraa 15.05.2020 09:26

Цитата:

Сообщение от laimas (Сообщение 524318)
В контексте приоритета операторов или?

Что такое приоритет?
В спецификации нет такого понятия.

laimas 15.05.2020 09:57

https://developer.mozilla.org/ru/doc...tor_Precedence

voraa 15.05.2020 10:32

mdn хорошая вещь.
Но это не спецификация, а только ее трактовка. Иногда не совсем полная.


Часовой пояс GMT +3, время: 19:34.