Почему Javascript OR возвращает значение, отличное от true/false?

Я видел эту конструкцию, чтобы получить ширину видового экрана браузера:

function () { return window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth; }

Я понимаю причастность к браузеру. Я не понимаю, почему || возвращает значение. Поэтому я попробовал это alert(undefined || 0 || 3); и, конечно же, он оповещает 3. Я нахожу это странным, потому что ожидаю true или false. Может ли кто-нибудь объяснить, что происходит?

Ответы

Ответ 1

Взгляните на раздел стандартов ECMAScript 11.11 Бинарные логические операторы

Производственное логическое выражение: Логическое выражение Логическое выражениеВыражение оценивается как следующим образом:

1.Evaluate LogicalORExpression.

2.Call GetValue (Результат (1)).

3.Call ToBoolean (Результат (2)).

4.Если результат (3) истинен, верните результат (2).

5.Evaluate LogicalANDExpression.

6.Call GetValue (результат (5)).

7. Возврат результата (6).

Таким образом, он вычисляет логическое преобразование каждого операнда, но возвращает фактическое значение операнда.

Если вы хотите знать, как Javascript преобразует значения в логическое, см. раздел 9.2 ToBoolean

Ответ 2

Оператор JavaScript || определен для возврата левого значения, если он оценивает правдивое значение, в противном случае - правильное значение вместо возврата true. Вот как это определено в спецификации.

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

Ответ 3

Не думайте об этом как о "или". Это больше похоже на устройство контроля потока в выражении. Значение a || выражение - это значение первого подвыражения, которое "правдиво". Таким образом, оценка серии подвыражений останавливается в какой-то момент, как если бы

 expr1 || expr2 || expr3

были

 (function() {
   var rv = expr1;
   if (rv) return rv;
   rv = expr2;
   if (rv) return rv;
   return expr3;
 })()

Ответ 4

Функция OR - это короткое замыкание ИЛИ оценка - она ​​возвращает первый элемент, который не является ложным, или последний неверный элемент в противном случае.

Это действительно полезно, поэтому вы можете писать выражения типа

a = a || someValue;

То же, что и

if (a==null)
  a = someValue;

Ответ 5

Это так, как по дизайну. ||, как && является оператором короткого замыкания, выражения оцениваются по порядку, они останавливаются после того, как выражение соответствует критериям и дает результат выражения. То же самое относится к &&:

var  myObj  = { "Test": { "Foo":"Bar" } };
var  myObj2 = { "Foo": "Bar" };

alert(myObj.Test && myObj.Test.Foo); // will alert "Bar";
alert(myObj2.Test && myObj2.Test.Foo); // will alert undefined;

Ответ 6

Некоторые значения, такие как ноль, "" или undefined, считаются ложными. Все остальное верно, поэтому оператор || просто возвращает первое ненулевое (т.е. истинное) значение в паре, которую он дал. Это полезно для трюков, таких как код выше, но я предполагаю, что он не был добавлен на язык, чтобы позволить вам пропустить оператор odd if.

Я подозреваю, что это могло произойти как настройка производительности, поскольку языки более высокого уровня (такие как BASIC... да, возможно, странное определение более высокого уровня) использовали фиксированные константы для истинных и ложных - часто 0 и -1, или 0 и 1.