JavaScript && 及 || 操作
和类C语言一样,JavaScript定义 && 及 || 分别表示逻辑与、或操作。使用true和false两个布尔值可生成下列真值表:
// Logical AND operation
true && true; // true
true && false; // false
false && true; // false
false && false; // false
// Logical OR operation
true || true; // true
true || false; // true
false || true; // true
false || false; // false
对于与操作,只有两者都为true才返回true,其他情况返回false;而或操作,仅两者都为false才返回false,其他期刊返回true。
1. 对非布尔值使用逻辑操作
在JavaScript中逻辑操作与类C语言语义不同,可以对任何类型表达式执行逻辑操作,不仅仅局限于布尔类型,而且逻辑操作不总是返回布尔值,请参加规范说明:
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.
下面示例显示布尔操作结果情况:
"foo" && "bar"; // "bar"
"bar" && "foo"; // "foo"
"foo" && ""; // ""
"" && "foo"; // ""
"foo" || "bar"; // "foo"
"bar" || "foo"; // "bar"
"foo" || ""; // "foo"
"" || "foo"; // "foo"
&& 、|| 的结果恰为两个操作表示式其中之一。
- A && B 如果A能强制转为false则返回A,否则返回B.
- A || B 如果A能强制转为true则返回A,否则返回B.
其结果总是两操作表达式其中之一,如 Kyle Simpson 《You Don’t Know JS》描述:
In fact, I would argue these operators shouldn’t even be called “logical operators”, as that name is incomplete in describing what they do. If I were to give them a more accurate (if more clumsy) name, I’d call them “selector operators,” or more completely, “operand selector operators.”
2. 控制流结构即真值
实际上我们可能没有注意到 && 及 || 并不总是返回布尔值。像if表达式或循环结构只有当评估条件为真时才会执行结构体语句,但并不是非要布尔值:
let values = [1, 2, 3];
while (values.length) {
console.log(values.pop());
}
// 3
// 2
// 1
那么什么样的表达式被认为是真值呢?在JavaScript中所有值都被认为真值,除了下面六个假值:
- false
- undefined
- null
- NaN
- 0 (both +0 and -0)
- “”
上面while循环中,当最后一个元素删除后,values.length返回0即假值。因此循环体不再执行并终止。
3. 函数返回值
现在看一个示例,&&和||并不一定产生一个布尔值。web应用中,用户可以登出,此时user对象为null,或者登录后user对象存在并包括一个isAdmin属性。
如果需要检查当前用户是否为管理员,首先需要检查user是否已认证(即user不为null),然后访问isAdmin属性是否为真:
let user = { isAdmin: true };
// ...
if (user && user.isAdmin) {
// ...
}
你可能会想抽取user && user.isAdmin
表示式至单独isAdministrator
函数中,可以在多个地方重复使用:
function isAdministrator(user) {
return user && user.isAdmin;
}
let user = { isAdmin: true };
if (isAdministrator(user)) {
// ...
}
user对象包括isAdmin属性,无论true和false返回结果和预期的一样:
isAdministrator({ isAdmin: true }); // true
isAdministrator({ isAdmin: false }); // false
但user对象为null会发生什么?
isAdministrator(null); // null
user && user.isAdmin
表达式的结果为null,即第一个操作表达式被返回,因为user为空被视为false。isAdministrator
函数应该仅返回布尔值,就如名称is
所表明的,但结果却包括null。
4. 强制转换为布尔值
在JavaScript中,常用的强制转换任何类型值为布尔值是使用逻辑取反操作!
两次:
function isAdministrator(user) {
return !!(user && user.isAdmin);
}
如果单个操作数可强制转成true,那么!操作返回false;否则返回true。其结果总是布尔值,但操作数的值被反转,因此应用两次!操作:
!!true = !false = true
!!false = !true = false
!!0 = !true = false
!!1 = !false = true
另外一种方法使用Boolean函数,其可以更加清晰转换给定值为布尔类型:
function isAdministrator(user) {
return Boolean(user && user.isAdmin);
}
5. 总结
JavaScript中 && 、 || 并不总是返回布尔值,两者总是返回其中一个操作数。使用两个!!或Boolean函数可以正确返回布尔类型。
本文参考链接:https://blog.csdn.net/neweastsun/article/details/104106946