Почему логические операторы (&& и ||) не всегда возвращают логический результат? - PullRequest
47 голосов
/ 24 марта 2011

Почему эти логические операторы возвращают объект, а не логическое значение?

var _ = (obj.fn && obj.fn() ) || obj._ || ( obj._ = {} );

var _ = obj && obj._;

Я хочу понять, почему он возвращает результат obj.fn() (если он определен) ИЛИ obj._, но не логический результат.

Ответы [ 8 ]

66 голосов
/ 20 декабря 2011

В JavaScript и ||, и && являются логическими операторами короткого замыкания, которые возвращают первое полностью определенное «логическое значение» при оценке слева направо.

В выражении X || Y, X сначала оценивается и интерпретируется как логическое значение. Если это логическое значение «true», оно возвращается. И Y не оценивается. (Поскольку не имеет значения, является ли Y истинным или Y ложным, X || Y полностью определен.) Это часть короткого замыкания.

Если это логическое значение равно «false», то мы все равно не будем знать, является ли X || Y истиной или ложью, до тех пор, пока не оценим Y и не будем интерпретировать его как логическое значение. Итак, Y возвращается.

И && делает то же самое, за исключением того, что останавливает оценку, если первый аргумент имеет значение false.

Первая сложная часть заключается в том, что когда выражение оценивается как «true», тогда возвращается само выражение. Который считается «истинным» в логических выражениях, но вы также можете использовать его Вот почему вы видите фактические возвращаемые значения.

Вторая сложность заключается в том, что когда выражение оценивается как «ложное», то в JS 1.0 и 1.1 система возвращает логическое значение «ложное»; тогда как в JS 1.2 он возвращает фактическое значение выражения.

В JS false, 0, -0, "", null, undefined, NaN и document.all все считаются ложными .

Здесь я, конечно, цитирую логические значения для обсуждения. Конечно, буквенная строка "false" не совпадает со значением false, и поэтому имеет значение true.

53 голосов
/ 22 августа 2015

Проще говоря:

Оператор || возвращает первое истинное значение, и если ни одно из них не является правдивым, оно возвращает последнее значение (которое является ложным значением).Оператор && возвращает первое ложное значение, и если ни одно из них не является ложным, оно возвращает последнее значение (которое является истинным значением).

Это действительно так просто.Поэкспериментируйте в своей консоли, чтобы убедиться в этом.

"" && "Dog"    // ""
"Cat" && "Dog" // "Dog"
"" || "Dog"    // "Dog"
"Cat" || "Dog" // "Cat"
17 голосов
/ 24 марта 2011
var _ = ((obj.fn && obj.fn() ) || obj._ || ( obj._ == {/* something */}))? true: false 

вернет логическое значение.

ОБНОВЛЕНИЕ

Обратите внимание, что это основано на моем тестировании.Я не должен полностью полагаться.

Это выражение, которое не присваивает true или false значение.Скорее, он присваивает рассчитанное значение.

Давайте посмотрим на это выражение.

Пример выражения:

var a = 1 || 2;
// a = 1

// it's because a will take the value (which is not null) from left
var a = 0 || 2;
// so for this a=2; //its because the closest is 2 (which is not null)

var a = 0 || 2 || 1;    //here also a = 2;

Ваше выражение:

var _ = (obj.fn && obj.fn() ) || obj._ || ( obj._ = {} );

// _ = closest of the expression which is not null
// in your case it must be (obj.fn && obj.fn())
// so you are gettig this

Другое выражение:

var a = 1 && 2;
// a = 2

var a = 1 && 2 && 3;
// a = 3 //for && operator it will take the fartest value
// as long as every expression is true

var a = 0 && 2 && 3;
// a = 0

Другое выражение:

var _ = obj && obj._;

// _ = obj._
3 голосов
/ 27 апреля 2013

Я думаю, у вас есть базовый вопрос по методологии JavaScript здесь.

Теперь JavaScript является свободно типизированным языком. Таким образом, способ и способ обработки логических операций отличается от других стандартных языков, таких как Java и C ++. JavaScript использует концепцию, известную как «приведение типов», для определения значения логической операции и всегда возвращает значение первого типа true. Например, взгляните на код ниже:

var x = mystuff || document;
// after execution of the line above, x = document

Это потому, что mystuff - это априорная неопределенная сущность, которая всегда будет оцениваться в false при тестировании, и поэтому JavaScript пропускает это и проверяет следующую сущность на значение true. Поскольку объект документа известен JavaScript, он возвращает значение true, а JavaScript возвращает этот объект.

Если вы хотите, чтобы вам было возвращено логическое значение, вам пришлось бы передать свой оператор логического условия в функцию, подобную следующей:

var condition1 = mystuff || document;

function returnBool(cond){
  if(typeof(cond) != 'boolean'){ //the condition type will return 'object' in this case
     return new Boolean(cond).valueOf();
  }else{ return; }
}    
// Then we test...
var condition2 = returnBool(condition1);
window.console.log(typeof(condition2)); // outputs 'boolean' 
2 голосов
/ 13 февраля 2017

В большинстве языков программирования операторы && и || возвращают логическое значение. В JavaScript это отличается .


ИЛИ Оператор:

Возвращает значение первого операнда , который проверяется как true (если есть), в противном случае он возвращает значение последнего операнда (даже если он проверяется как ложь) .

Пример 1:

var a = 0 || 1 || 2 || 3;
        ^    ^    ^    ^
        f    t    t    t
             ^
             first operand that validates as true
             so, a = 1

Пример 2:

var a = 0 || false || null || '';
        ^    ^        ^       ^
        f    f        f       f
                              ^
                              no operand validates as true,
                              so, a = ''

И оператор:

Возвращает значение последнего операнда , который проверяется как истина (если все условия подтверждаются как истина), в противном случае возвращается значение первого операнда , который проверяет как ложь .

Пример 1:

var a = 1 && 2 && 3 && 4;
        ^    ^    ^    ^
        t    t    t    t
                       ^
                       last operand that validates as true
                       so, a = 4

Пример 2:

var a = 2 && '' && 3 && null;
        ^    ^     ^    ^
        t    f     t    f
             ^
             entire condition is false, so return first operand that validates as false,
             so, a = ''

Вывод:

Если вы хотите, чтобы JavaScript работал так же, как другие языки программирования, используйте функцию Boolean(), например:

var a = Boolean(1 || 2 || 3);// a = true
2 голосов
/ 11 января 2013

Мы можем обратиться к спецификации (11.11) JS здесь:

Семантика

Производство LogicalANDExpression: LogicalANDExpression && BitwiseORExpression оценивается следующим образом:

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

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

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

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

5. Оценить побитовое выражение.

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

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

см. здесь для спецификации

1 голос
/ 11 января 2013

Сравните:

var prop;
if (obj.value) {prop=obj.value;}
else prop=0;

с:

var prop=obj.value||0;

Возвращение истинного выражения, а не просто истинного или ложного, обычно делает ваш код короче и по-прежнему читаемым.Это очень часто встречается для ||, а не для &&.

1 голос
/ 24 марта 2011

Во-первых, возвращение должно быть правдой, поэтому, если вы проверяете на правдивость, тогда это не имеет значения

Во-вторых, он позволяет вам выполнять задания в соответствии с:

function bar(foo) {
    foo = foo || "default value";
...