Преобразование типов для примитивов [дубликат]

143
14 февраля 2019, 04:50

На данный вопрос уже ответили:

  • && и || с разными типами данных 3 ответа

Читаю про преобразование типов в JavaScript. Не поняла, что происходит в следующих случаях:

alert(5 && 2); // 2
alert(2 && 5); // 5
alert(5 || 0); // 5

Я сначала думала, что будет преобразование к логическому типу и далее операции уже с преобразованными данными. Но нет. Другой вариант - логическая операция операция работает как побитовая, но тоже что-то не то.

Подскажите, что конкретно происходит в этих примерах?

Answer 1

Я сначала думала, что будет преобразование к логическому типу и далее операции уже с преобразованными данными. Но нет.

На самом деле да. Сравнение операндов действительно производится только после приведения их к логическому типу. Вот только возвращается не true или false, а непосредственно один из операндов.

Вот, что написано в спецификации по этому поводу:

The value produced by a && or || operator is not necessarily of type Boolean. The value produced will always be the value of one of the two operand expressions.

В секции 12.13.3 приведены непосредственно сами алгоритмы (о них еще более подробно ниже) работы этих операторов (|| и &&), из которых видно, что операнды действительно преобразуются к boolean типу.

Здесь основная сложность может возникнуть с самим приведением, однако в последней редакции спецификации появилась очень удобная табличка, в которой в человеко-понятной форме расписано, какие значения к чему приводятся. Советую ознакомиться, если есть необходимость.

Возвращаемое значение

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

Оператор &&
Если левый операнд преобразуется к false, то он и возвращается. В противном случае возвращается правый операнд:

// Везде вернется левый операнд, поскольку он преобразуется к `false`. 
// И даже если и правый операнд тоже преобразуется к false, то все равно будет возвращен левый (случаи 4-6). 
let examples = [0 && true, false && "string", "" && 82, 0 && false, false && "", "" && 0]; 
 
examples.forEach((example) => { 
  console.log(example); 
});

Оператор ||

Здесь левый операнд всегда будет возвращен наоборот только в том случае, если он приводится к true:

// Если левый операнд приводится к true, то он же и возвращается. 
// И даже если и правый операнд тоже приводится к true, то все равно возвращается левый (случаи 3 и 4). 
// Однако если ни один из них не приводится к true, то возвращается последний (правый) (случаи 5 и 6). 
let examples = [true || false, "string" || "", true || true, 1 || [], false || 0, 0 || ""]; 
 
examples.forEach((example) => { 
  console.log(example); 
});

Answer 2

Согласно MDN:

expr1 && expr2 возвращает значение expr1, если оно может быть преобразовано в false; иначе возвращает значение expr2

Так как в первом примере expr1 (5) преобразуется к true, то возвращается expr2 (2). Аналогично со вторым примером

expr1 || expr2 возвращает значение expr1, если оно может быть преобразовано в true; иначе возвращает значение expr2

В третьем примере expr1 (5) преобразуется к true, поэтому оно и возвращается

READ ALSO
JavaScript, P5.JS, Canvas - Размер канвы и странности метода rect()

JavaScript, P5.JS, Canvas - Размер канвы и странности метода rect()

Использую библиотеку P5JS чтобы нарисовать квадрат шириной и высотой во всю канву:

166
Получить число после зяпятой

Получить число после зяпятой

Есть число 25652, как получить оставшееся число после точки?

161
Как на js проверить человек зашел или робот?

Как на js проверить человек зашел или робот?

Как на js можно определить кто зашел на сайт? робот или человек? Потому что для человека нужно показать секретные блоки, которые роботу нельзя...

171