оператор '& & ' в Javascript vs в Java
В настоящее время я читаю JavaScript из JavaScript: The Definitive Guide. На странице 76 написано следующее утверждение:
o && o.x // => 1: o is truthy, so return value of o.x
Будучи программистом Java, я хочу спросить, почему он возвращает 1 вместо 'true'
в Java этого не было, но в любом случае я знаю, что JavaScript отличается, но логика и механизм везде одинаковы.(В C он возвращает 1 как true.)
Я спрашиваю, почему это вообще имеет смысл для такого поведения?
Есть ли какой-нибудь способ, Я могу гарантировать возврат только истинных или ложных значений?
6 ответов:
Согласно спецификации для бинарных логических операторов
Значение, производимое оператором && или||, не обязательно имеет тип Логический. Произведенная ценность всегда будет ценностью одного из двух выражения операндов.
Эта функция часто используется в javascript, один из распространенных случаев использования-присвоение переменной значения по умолчанию, если она не определена. Например, предположим, что вы ожидаете объект options в качестве param, но не является обязательным, поэтому пользователь может не пройти это
function x(options){ options = options || {}; //now your can access optionx.a without fearing whether options is undefined }
Вы можете сделать что-то вроде
!!(o && o.x)
, чтобы всегда получать true / false
Если у нас есть:
expr1 && expr2
&& возвращает выражение1, если оно может быть преобразовано в false; иначе возвращает 'выражение2'. Таким образом, при использовании с логическими значениями && возвращает true, если оба операнда имеют значение true; в противном случае возвращает false.
Итак, если мы имеем:
Var xyz = a && b;
//где a-неопределенный (false), А b-123, то он будет выделять неопределенный.В случае операторов if эти значения специально преобразуются в boolean.
См. следующую ссылку: "https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Logical_Operators"
Возвращает значение правого операнда. Если бы значение
o.x
былоtrue
, оно вернуло быtrue
. Если бы значениеo.x
было'banana'
, оно вернуло бы'banana'
.
var o = {x:true}; console.log(o && o.x);
Технически оператор
&&
реализован для возврата первого операнда, если его значение не равно нулю, и возвращает второй операнд в противном случае во многих языках, включая Java, C/C++, Javascript, Perl... В то время как большинство языков принимает любой тип операндов, Java заставляет вас использовать логические операнды, поэтому он всегда возвращает true или false. Для принудительного получения логического результата в Javascript используйте:Boolean(a && b)
Такое поведение называется принуждением. Принуждение - это действие, заставляющее объект вести себя как другой тип, и логические операторы могут производитьпринуждение при попытке получить доступ к значению оцениваемого объекта.
Важно помнить таблицу дляистинных иложных значений, потому что из-за принуждения могут быть получены различные результаты.
false
производитfalse
0
производитfalse
“”
производитfalse
NaN
производитfalse
null
производитfalse
undefined
производитfalse
Все остальное производит
true
, включая текст"0"
и"false"
, функции, массивы и пустые объекты.Учитывая правила для логических операторов, существует оценка короткого замыкания в JavaScript, например:
0 && 1; //-> 0, falsy value !(0 && 1); //-> true, falsy value negated !!(0 && 1); //-> false, boolean falsy value void 0 && alert("1") //-> undefined (void produces undefined) [] && Math.ceil(9.1) //-> 10, truthy value {} && someFunc() //-> the result of someFunc() 0 || null; //-> null, falsy value null || "0"; //-> "0", truthy value "" || void 1; //-> undefined, falsy value !!(+"5px" || {}); //-> true, boolean truthy value
Принуждение полезно, когда вы должны проверить значения по умолчанию, для предотвращения ошибок, например
function divide (a, b) { a = +a; //-> coerced to number b = +b; //-> coerced to number if (!a) return 0; //-> NaN or zero return b && a / b; //-> b must be a number different from zero } divide(); //-> 0 divide(5); //-> NaN, no error thrown! divide(5, "a"); //-> NaN, no error thrown! divide(5, 0); //-> 0, division by zero prevented! divide(49, 6); //-> 8.1666
Если вы хотите предотвратить возврат
NaN
, просто добавьте еще одно принуждение в оператор return:return (b && a / b) || 0;
Вы можете проверить другие случаи принуждения: JavaScript принуждение
счастливого кодирования!