JavaScript 里有三个逻辑运算符:||
(或),&&
(与),!
(非)。javascript
虽然他们被称为“逻辑”运算符,但这些运算符却能够被应用于任意类型的值,而不只仅是布尔值。他们的结果也一样能够是任意类型。html
让咱们来详细看一下。java
两个竖线符号表示了“或”运算:react
result = a || b;
复制代码
在传统的编程中,逻辑或仅可以操做布尔值。若是参与运算的任意一个参数为 true
,返回的结果就为 true
,不然返回 false
。算法
在 JavaScript 中,逻辑运算符更加灵活强大。可是首先咱们看一下操做数是布尔值的时候发生了什么。编程
下面是四种可能的逻辑组合:微信
alert( true || true ); // true
alert( false || true ); // true
alert( true || false ); // true
alert( false || false ); // false
复制代码
正如咱们所见,除了两个操做数都是 false
的状况,结果都是 true
。ide
若是操做数不是布尔值,那么它将会被转化为布尔值来参与运算。函数
例如,数字 1
将会被做为 true
,数字 0
则做为 false
:学习
if (1 || 0) { // 工做原理至关于 if( true || false )
alert( 'truthy!' );
}
复制代码
大多数状况,逻辑或 ||
会被用在 if
语句中,用来测试是否有 任何 给定的条件为 true
。
例如:
let hour = 9;
if (hour < 10 || hour > 18) {
alert( 'The office is closed.' );
}
复制代码
咱们能够传入更多的条件:
let hour = 12;
let isWeekend = true;
if (hour < 10 || hour > 18 || isWeekend) {
alert( 'The office is closed.' ); // 是周末
}
复制代码
上文提到的逻辑处理多少有些传统了。下面让咱们看看 JavaScript 的“附加”特性。
拓展的算法以下所示。
给定多个参与或运算的值:
result = value1 || value2 || value3;
复制代码
或运算符 ||
作了以下的事情:
true
,就中止计算,返回这个操做数的初始值。false
),则返回最后一个操做数。返回的值是操做数的初始形式,不会作布尔转换。
也就是,一个或 "||"
运算的链,将返回第一个真值,若是不存在真值,就返回该链的最后一个值。
例如:
alert( 1 || 0 ); // 1(1 是真值)
alert( true || 'no matter what' ); //(true 是真值)
alert( null || 1 ); // 1(1 是第一个真值)
alert( null || 0 || 1 ); // 1(第一个真值)
alert( undefined || null || 0 ); // 0(全部的转化结果都是 false,返回最后一个值)
复制代码
与“纯粹的、传统的、仅仅处理布尔值的或运算”相比,这个规则就引发了一些颇有趣的用法。
获取变量列表或者表达式的第一个真值。
假设咱们有几个变量,它们可能包含某些数据或者是 null/undefined
。咱们须要选出第一个包含数据的变量。
咱们能够这样应用或运算 ||
:
let currentUser = null;
let defaultUser = "John";
let name = currentUser || defaultUser || "unnamed";
alert( name ); // 选出了 “John” — 第一个真值
复制代码
若是 currentUser
和 defaultUser
都是假值,那么结果就是 "unnamed"
。
短路取值。
操做数不只仅能够是值,还能够是任意表达式。或运算会从左到右计算并测试每一个操做数。当找到第一个真值,计算就会中止,并返回这个值。这个过程就叫作“短路取值”,由于它尽量地减小从左到右计算的次数。
当表达式做为第二个参数而且有必定的反作用(side effects),好比变量赋值的时候,短路取值的状况就清楚可见。
若是咱们运行下面的例子,x
将不会被赋值:
let x;
true || (x = 1);
alert(x); // undefined,由于 (x = 1) 没有被执行
复制代码
若是第一个参数是 false
,或运算将会继续,并计算第二个参数,也就会运行赋值操做。
let x;
false || (x = 1);
alert(x); // 1
复制代码
赋值操做只是一个很简单的状况。可能有反作用,若是计算没有到达,反作用就不会发生。
正如咱们所见,这种用法是“if
语句的简短方式”。第一个操做数被转化为布尔值,若是是假,那么第二个参数就会被执行。
大多数状况下,最好使用常规的 if
语句,这样代码可读性更高,可是有时候这种方式会很简洁。
两个 & 符号表示 &&
与操做:
result = a && b;
复制代码
传统的编程中,当两个操做数都是真值,与操做返回 true
,不然返回 false
:
alert( true && true ); // true
alert( false && true ); // false
alert( true && false ); // false
alert( false && false ); // false
复制代码
使用 if
语句的例子:
let hour = 12;
let minute = 30;
if (hour == 12 && minute == 30) {
alert( 'Time is 12:30' );
}
复制代码
就像或运算同样,与运算的操做数能够是任意类型的值:
if (1 && 0) { // 做为 true && false 来执行
alert( "won't work, because the result is falsy" );
}
复制代码
给出多个参加与运算的值:
result = value1 && value2 && value3;
复制代码
与运算 &&
作了以下的事:
false
,就中止计算,并返回这个操做数的初始值。true
),则返回最后一个操做数。换句话说,与操做符返回第一个假值,若是没有假值就返回最后一个值。
上面的规则和或运算很像。区别就是与运算返回第一个假值而或操做返回第一个真值。
例如:
// 若是第一个操做符是真值,
// 与操做返回第二个操做数:
alert( 1 && 0 ); // 0
alert( 1 && 5 ); // 5
// 若是第一个操做符是假值,
// 与操做直接返回它。第二个操做数被忽略
alert( null && 5 ); // null
alert( 0 && "no matter what" ); // 0
复制代码
咱们也能够在一行代码上串联多个值。查看第一个假值是否被返回:
alert( 1 && 2 && null && 3 ); // null
复制代码
若是全部的值都是真值,最后一个值将会被返回:
alert( 1 && 2 && 3 ); // 3,最后一个值
复制代码
与运算
&&
在或操做符||
以前执行与运算
&&
的优先级比或运算||
要高。因此代码
a && b || c && d
彻底跟&&
表达式加了括号同样:(a && b) || (c && d)
。
就像或运算同样,与运算 &&
有时候可以代替 if
。
例如:
let x = 1;
(x > 0) && alert( 'Greater than zero!' );
复制代码
&&
右边的代码只有运算抵达到那里才能被执行。也就是,当且仅当 (x > 0)
返回了真值。
因此咱们基本能够相似地获得:
let x = 1;
if (x > 0) {
alert( 'Greater than zero!' );
}
复制代码
带 &&
的代码变体看上去更短。可是 if
的含义更明显,可读性也更高。
因此建议是根据目的选择代码的结构。须要条件判断就用 if
,须要与运算就用 &&
。
感叹符号 !
表示布尔非运算。
语法至关简单:
result = !value;
复制代码
操做符接受一个参数,并按以下运做:
true/false
。例如:
alert( !true ); // false
alert( !0 ); // true
复制代码
两个非运算 !!
有时候用来将某个值转化为布尔类型:
alert( !!"non-empty string" ); // true
alert( !!null ); // false
复制代码
也就是,第一个非运算将该值转化为布尔类型并取反,第二个非运算再次取反。最后咱们就获得了一个任意值到布尔值的转化。
有更多详细的方法能够完成一样的事 —— 一个内置的 Boolean
函数:
alert( Boolean("non-empty string") ); // true
alert( Boolean(null) ); // false
复制代码
非运算符 !
的优先级在全部逻辑运算符里面最高,因此它老是在 &&
和 ||
前执行。
先本身作题目再看答案。
重要程度:⭐️⭐️⭐️⭐️⭐️
以下代码将会输出什么?
alert( null || 2 || undefined );
复制代码
重要程度:⭐️⭐️⭐
下面的代码将会输出什么?
alert( alert(1) || 2 || alert(3) );
复制代码
重要程度:⭐️⭐️⭐️⭐️⭐️
下面这段代码将会显示什么?
alert( 1 && null && 2 );
复制代码
重要程度:⭐️⭐️⭐
这段代码将会显示什么?
alert( alert(1) && alert(2) );
复制代码
重要程度:⭐️⭐️⭐️⭐️⭐️
结果将会是什么?
alert( null || 2 && 3 || 4 );
复制代码
重要程度:⭐️⭐️⭐
写一个“if”条件句来检查 age
是否位于 14
到 90
的闭区间。
“闭区间”意味着,age
的值能够取 14
或 90
。
重要程度:⭐️⭐️⭐
写一个 if
条件句,检查 age
是否不位于 14 到 90 的闭区间。
建立两个表达式:第一个用非运算 !
,第二个不用。
重要程度:⭐️⭐️⭐️⭐️⭐️
下面哪个 alert
将会被执行?
if(...)
语句内表达式的结果是什么?
if (-1 || 0) alert( 'first' );
if (-1 && 0) alert( 'second' );
if (null || -1 && 1) alert( 'third' );
复制代码
重要程度:⭐️⭐️⭐
实现使用 prompt
进行登录校验的代码。
若是访问者输入 "Admin"
,那么使用 prompt
引导获取密码,若是输入的用户名为空或者按下了 key:Esc
键 —— 显示 "Canceled",若是是其余字符串 —— 显示 "I don't know you"。
密码的校验规则以下:
流程图:
请使用嵌套的 if
块。注意代码总体的可读性。
提示:将空字符串输入,prompt 会获取到一个空字符串 ''
。Prompt 运行过程当中,按下 key:ESC
键会获得 null
。
在微信公众号「技术漫谈」后台回复 1-2-11
获取本题答案。
现代 JavaScript 教程:开源的现代 JavaScript 从入门到进阶的优质教程。React 官方文档推荐,与 MDN 并列的 JavaScript 学习教程。
在线免费阅读:zh.javascript.info
扫描下方二维码,关注微信公众号「技术漫谈」,订阅更多精彩内容。