Почему Javascript OR возвращает значение, отличное от true / false? - PullRequest
18 голосов
/ 03 июня 2010

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

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

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

Ответы [ 6 ]

22 голосов
/ 03 июня 2010

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

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

18 голосов
/ 03 июня 2010

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

Производственная логическая экспрессия: LogicalORExpression || LogicalANDExpression оценивается как следующим образом:

1. Оцените логическое выражение выражения.

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

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

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

5. Оценка логического выражения и выражения.

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

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

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

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

13 голосов
/ 03 июня 2010

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

 expr1 || expr2 || expr3

были

 (function() {
   var rv = expr1;
   if (rv) return rv;
   rv = expr2;
   if (rv) return rv;
   return expr3;
 })()
6 голосов
/ 03 июня 2010

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

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

a = a || someValue;

То же самое, что и

if (a==null)
  a = someValue;
2 голосов
/ 03 июня 2010

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

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;
1 голос
/ 03 июня 2010

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...