Почему || (или) и оператор && (и) в JavaScript ведут себя иначе, чем в C (возвращая не логическое значение)?

Рассмотрим следующий код.

console.log("All" && 1); // 1
console.log("All" || 1); // "All" 

Как видите, первое выражение, "All" && 1, оценивается как 1. Что, безусловно, не является логическим значением (не true). Я ожидал здесь более конкретной правды. Потому что я не форсировал результат как String.

Второе выражение, "All" || 1, оценивается как All. Что также не является логическим значением.

В языке C оба выражения оцениваются как 1. Поскольку я заставляю результат преобразовываться в строку.

#include <stdio.h>

int main() {
    printf("%d\n", "All" && 1); // 1
    printf("%d\n", "All" || 1); // 1
    return 0;
}

Почему JavaScript ведет себя иначе? В частности, почему JS возвращает не логическое значение?


person Bapi    schedule 02.09.2019    source источник


Ответы (2)


Логические операторы в C всегда возвращают логические значения. В C int 1 представляет true, а int 0 представляет false. Вот почему оба выражения, "All" && 1 и "All" || 1, оцениваются как 1. Оба они логически верны. Для пояснения рассмотрим следующую программу.

#include <stdio.h>

int main() {
    printf("%d\n", 20 && 10); // 1
    printf("%d\n", 20 || 10); // 1
    return 0;
}

В приведенной выше программе выражения 20 && 10 и 20 || 10 по-прежнему оцениваются как 1, хотя в этих выражениях нет 1. Это имеет смысл, потому что оба эти выражения логически верны. Следовательно, они оцениваются как 1, что эквивалентно true в JavaScript.

Если бы JavaScript вел себя так, как C, тогда выражения "All" && 10 и "All" || 10 оценивались бы как логическое значение true. Однако логические операторы ведут себя в JavaScript иначе. Это не значит, что они глючат.

Значения в JavaScript имеют понятие истинности и ложности. Например, значения true, "All", 10, [10, 20], { foo: 10 } и x => 2 * x верны. С другой стороны, значения false, "", 0, undefined и null являются ложными.

Логические операторы JavaScript не всегда возвращают логические значения, как это делает C. Вместо этого они вычисляют один из своих операндов. Оператор && оценивает свой левый операнд, если он ложный. В противном случае он возвращает правильный операнд. Точно так же оператор || оценивает свой левый операнд, если он правдив. В противном случае он возвращает правильный операнд.

Теперь значение "All" соответствует действительности. Следовательно, "All" && 1 оценивается как правый операнд (т.е. 1), тогда как "All" || 1 оценивается как левый операнд (т.е. "All"). Обратите внимание, что и 1, и "All" являются истинными значениями, что означает, что они эквивалентны 1 (что представляет собой правдивость) в C.

Следовательно, нет. JavaScript не глючит.

person Aadit M Shah    schedule 02.09.2019

Я цитирую здесь официальный документ: - Логический И в JS

Логический оператор И (&&) (логическая конъюнкция) для набора операндов истинен тогда и только тогда, когда истинны все его операнды. Обычно он используется с булевыми (логическими) значениями. Когда это так, он возвращает логическое значение. Однако оператор && фактически возвращает значение одного из указанных операндов, поэтому, если этот оператор используется с нелогическими значениями, он вернет нелогическое значение.

Возьмем несколько примеров,

let a = [1,2,3];
console.log( 0 && a.b ); // return 0
console.log( 1 && a.b ); // return a type error.

В первом console.log, когда JavaScript сначала видит 0, интерпретатор JS останавливается и возвращает первое значение.

Это происходит потому, что когда интерпретатор JS переводит первое значение в логическое значение, оно оценивается как false. Мы знаем тот факт, что для любого оператора &&, если одно значение равно false, оно вернет false.

Таким образом, интерпретатор JS здесь пытается сэкономить вычислительную мощность, возвращаясь раньше, без полной оценки оператора. Это здорово.

То же самое относится и к оператору ЛОГИЧЕСКОЕ ИЛИ (||).

person Bapi    schedule 02.09.2019