js逻辑运算符是二元操作符,也叫二元布尔操作符,是基于逻辑(boolean)值的运算,返回的是 boolean 值。二元逻辑运算符主要包括:逻辑与 &&
、逻辑或 ||
和逻辑非 !
,二元布尔操作符是可短路的, 只有在必要时才会计算到最后一项。js条件运算符是js中唯一的三元操作运算符,它是将两个结果中符合运算逻辑的那个值返回。三元运算符一般用于替代if条件判断语句。
1、逻辑运算符
js中逻辑运算符也叫布尔操作符,在开发中是非常常见的,主要有三种:逻辑与 &&
、逻辑或 ||
和逻辑非 !
。布尔操作符是可短路的,只有在必要的时候才会计算到最后一项,即在一定条件下,只计算其中的一个值。
1.1 逻辑与 &&
&&
运算符,表示逻辑与(and),使用格式为:a&&b
,其中a和b均为表达式,运算顺序为从左到右,支持短路操作。即先计算 a 表达式的值,如果 a 为true,直接返回 b 表达式的值;如果 a 表达式计算的值为false,则直接返回false,不再计算 b 表达式的值。
- 两个表达式结果都为 true 时,结果才为 true。
- 只要有一个表达式结果为 false ,结果就为 false。
- 如果第一个表达式计算结果为 false ,结果为 false;且不再计算第二个表达式的值。
- 注意:当数值参与逻辑与运算时,结果为 true,返回的会是第二个为真的值;如果结果为 false,返回的会是第一个为假的值。
注:&& 优先级高于 ||
console.log(1 && 2); // 输出结果为2
console.log(1 && 2 && "flag"); // 输出结果为flag
console.log(1 && 2 && 0 && "flag"); // 输出结果为0
console.log((1 && 2 || 0) && 4); //输出结果为4
正例和反例:
//反例:不推荐写法
if (node) {
if (node.kids) {
if (node.kids[index]) {
foo(node.kids[index]);
}
}
}
//正例:推荐写法
var kid = node && node.kids && node.kids[index];
if (kid) {
foo(kid);
}
拓展:逻辑与分配 && =
此逻辑赋值运算符仅在左侧为真时才赋值。因此:x &&= y
等同于 x && (x = y)
1.2 逻辑或 ||
||
运算符,表示逻辑或(or),使用格式为:a||b
,其中a和b均为表达式,运算顺序为从左到右,支持短路操作。即先计算 a 表达式的值,如果 a 为true,直接返回 b 表达式的值;如果 a 表达式计算的值为false,则直接返回false,不再计算 b 表达式的值。
- 两个表达式中只要有一个结果为 true 时,结果就为 true。
- 两个表达式都为 false 时,结果才为 false。
- 如果第一个表达式计算结果为 true,结果为 true,且不再计算第二个表达式的值。
- 如果第一个表达式计算结果为 false,则计算第二个表达式的值并返回。
- 注意:当数值参与逻辑或运算时,结果为 true,返回的会是第一个为真的值;如果结果为 false,返回的会是第二个为假的值。
注:&& 优先级高于 ||
console.log(1||0); //输出结果为1
console.log(1 && 2 || 3 && 4); //输出结果为2
console.log((3||2)&&(5||0)); //输出结果为5
正例和反例:
//反例:不推荐写法
function foo(opt_win) {
var win;
if (opt_win) {
win = opt_win;
} else {
win = window;
}
//...
}
//正例:推荐写法
function foo(opt_win) {
var win = opt_win || window;
// ...
}
拓展:逻辑或分配 || =
此逻辑赋值运算符仅在左侧表达式为 falsy值时才赋值。Falsy与null有所不同,因为falsy可以是任何一种值:false,0,“”,null,undefined和NaN等。此逻辑赋值运算符仅在左侧为真时才赋值。
语法:x ||= y
等同于 x || (x = y)
1.3 逻辑非 !
!
运算符,表示逻辑非(not),为布尔取反操作。使用格式为:!a
,其中a为表达式。当 a 条件为false时,结果为true;反之亦然。
console.log(!1); //输出结果为false
console.log(!0); //输出结果为true
console.log(!false); //输出结果为true
console.log( ! {} ); //如果操作数是对象,则返回false
console.log( ! (n = 5)); //如果操作数是非零的任何数字,则返回false
console.log( ! null ); //如果操作数是null,则返回true
console.log( ! NaN ); //如果操作数是NaN,则返回true
console.log( ! Infinity ); //如果操作数是Infinity,则返回false
console.log( ! ( - Infinity )); //如果操作数是-Infinity,则返回false
console.log( ! undefined ); //如果操作数是undefined,则返回true
如果对操作数执行两次逻辑非运算操作,就相当于把操作数转换为布尔值。
console.log( ! 0 ); //返回true
console.log( ! ! 0 ); //返回false
逻辑与和逻辑或运算的返回值不一定是布尔值,但是逻辑非运算的返回值一定是布尔值。
1.4 数据类型的转换规则
- 非null对象为true;null对象为false。
- 非零数字为true;零为false。
- 非空字符串为true;空字符串为false。
- undefined为false。
- 其他为false。
2、三元操作符
条件运算符是JS中唯一的三元运算符,它将两个结果中其中一个符合运算逻辑的值返回。条件(三元)运算符使用格式为:b ? x : y
,其中 b 操作数必须是一个布尔类型的表达式(条件表达式,类型如果为非布尔值,会先将其转换为布尔类型),x 和 y 可以是任意类型的值。三元运算符一般用于替代if条件判断语句。
- 条件运算符在执行时, 首先对条件表达式进行求值。
- 如果操作数 b 的返回值为 true,则执行 x 操作数,并返回该表达式的值。
- 如果操作数 b 的返回值为 false,则执行 y 操作数,并返回该表达式的值。
- 如果条件的表达式的求值结果是一个非布尔值,会先将其转换为布尔类型,然后再运算。
2.1 条件运算符例子
// 定义变量 a,然后检测 a 是否被赋值,如果赋值则使用该值;否则设置默认值。
var a = null; //定义变量a
typeof a != "undefined" ? a = a : a = 0; //检测变量a是否赋值,否则设置默认值
console.log(a); //显示变量a的值,返回null
// 获取最大值
var a=30;var b=43;var c=50;
var max=a>b?a>c?a:c:b>c?b:c;//结果为50
// 写法2
var max=a>b?(a>c?a:c):(b>c?b:c);//结果为50
// 如果条件的表达式的求值结果是一个非布尔值,会先将其转换为布尔类型,然后再运算。
"hello"?alert(“语句1”):alert(“语句2”);// 结果alert(“语句1”);
注意:操作符始终写在前一行,以免分号的隐式插入产生预想不到的问题,正确的书写方式如下所示:
var x = a ? b : c;
var y = a ?
longButSimpleOperandB : longButSimpleOperandC;
var z = a ?
moreComplicatedB :
moreComplicatedC;
2.2 与上例相同效果的if语句
if(typeof a != "undefined"){ //赋值
a = a;
}else{ //没有赋值
a = 0;
}
console.log(a);
2.3 与上例相同效果的逻辑表达式
(typeof a != "undefined") && (a =a) || (a = 0); //逻辑表达式
console.log(a);
在上面的表达式中,如果 a 已赋值,则执行 (a = a) 表达式,执行完毕就不再执行逻辑或运算符后面的 (a = 0) 表达式;如果 a 未被赋值,则不再执行逻辑与运算符后面的 (a = a) 表达式,转而执行逻辑或运算符后面的表达式 (a = 0)。
- 注意:需要考虑假值的干扰,使用
typeof a != "undefined"
进行判断时,如果为变量赋值为false
、null
、""
、NaN
等假值时,也被误认为是没有赋值。
2.4 正例和反例
// 反例:不推荐写法
if (val != 0) {
return foo();
} else {
return bar();
}
// 正例:推荐写法
return val ? foo() : bar();
评论区