Почему оператор или в JavaScript ведет себя иначе, чем в C? [на удерживании]

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

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

Как видите, первое выражение, "All" && 1, правильно оценивается как 1. Я ожидал, что второе выражение, "All" || 1, также будет оценено как 1. Тем не менее, он оценивается в "All". Почему так?

В Си второе выражение правильно оценивается как 1.

#include <stdio.h>

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

Почему JavaScript ведет себя по-другому?

-15
задан Zoe 3 September 2019 в 12:03
поделиться

1 ответ

Логические операторы в C всегда оценивают к булевым значениям. В C интервал 1 представляет true, и интервал 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 110] даже при том, что нет никакого 1 в тех выражениях. Это имеет смысл, потому что оба тех выражения логически верны. Следовательно, они оценивают к [1 112], который эквивалентен [1 113] в JavaScript.

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

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

логические операторы JavaScript не всегда оценивают к булевым значениям как C, делает. Вместо этого они оценивают к одному из их операндов. && оператор оценивает к его левому операнду, если это - falsy. Иначе это оценивает к правильному операнду. Точно так же || оператор оценивает к его левому операнду, если это - truthy. Иначе это оценивает к правильному операнду.

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

Следовательно, нет. JavaScript не является багги.

5
ответ дан Aadit M Shah 10 September 2019 в 07:24
поделиться
Другие вопросы по тегам:

Похожие вопросы: