本文深入解析JavaScript中的三种逻辑运算符:逻辑非(!)、逻辑与(&&)和逻辑或(||)。详细阐述它们如何将任意值转换为布尔值进行运算,重点讲解短路求值机制及其在条件判断、默认值设置和回调控制中的实际应用,帮助开发者写出更简洁高效的代码。
逻辑运算符概述
前言
逻辑运算符用于对操作数执行布尔运算,常与关系运算符结合使用,将多个关系表达式组合成更复杂的逻辑表达式。JavaScript中的逻辑运算符主要包括逻辑非(!)、逻辑与(&&)和逻辑或(||)三种,下文将逐一解析。
逻辑非运算符(!)
逻辑非
逻辑非运算符由感叹号(!)表示,可作用于ECMAScript中的任何数据类型。无论操作数为何种类型,该运算符始终返回一个布尔值。其执行过程是先将操作数转换为布尔值,再对结果取反。
逻辑非对操作数进行布尔类型转换的规则与Boolean()转型函数一致,仅在最后一步执行取反操作。若连续使用两个逻辑非运算符(如!!value),其行为等同于模拟Boolean()转型函数,常用于将任意值显式转换为布尔类型。
console.log(!!undefined);//false
console.log(!!null);//false
console.log(!!0);//false
console.log(!!-0);//false
console.log(!!NaN);//false
console.log(!!'');//false
console.log(!!false);//false
console.log(!!{});//true
console.log(!![]);//true
console.log(!!new Boolean(false));//true
console.log(!!false);//false
console.log(!!new Boolean(null));//true
console.log(!!null);//false
逻辑非运算符常用于控制循环流程,例如在检索数据时通过取反条件判断是否继续循环。
//Boolean 变量(bFound)用于记录检索是否成功。找到问题中的数据项时,bFound 将被设置为true,!bFound将等于false,意味着运行将跳出while循环
var bFound = false;
var i = 0;
while (!bFound) {
if (aValue[i] == vSearchValues) {
bFound = true;
} else {
i++;
}
}
逻辑与运算符(&&)
逻辑与
逻辑与运算符由两个和号(&&)表示,包含两个操作数。仅当两个操作数均为true时,运算结果才为true;否则返回false。
//逻辑与(&&)的真值表
第一个操作数 第二个操作数 结果
true true true
true false false
false true false
false false alse
逻辑与运算符可应用于任意类型的操作数,而不仅限于布尔值。当操作数非布尔类型时,运算结果未必是布尔值,而是返回其中一个操作数的原始值。
逻辑与运算具有短路特性:若第一个操作数足以决定最终结果,则不再对第二个操作数求值。
具体而言,若第一个操作数为false(假值),则无论第二个操作数为何值,结果均为false,并返回第一个操作数;若第一个操作数为true(真值),则结果取决于第二个操作数,并返回第二个操作数的值。
//除了false、undefined、null、+0、-0、NaN、''这7个假值,其余都是真值
console.log('t' && ''); //因为't'是真值,所以返回''
console.log('t' && 'f'); //因为't'是真值,所以返回'f'
console.log('t' && 1 + 2); //因为't'是真值,所以返回3
console.log('' && 'f'); //因为''是假值,所以返回''
console.log('' && ''); //因为''是假值,所以返回''
var i = 1;
var result = (true && i++);
console.log(result,i);//因为true是真值,所以执行i++,i是2,result是1
var i = 1;
var result = (false && i++);
console.log(result,i);//因为false是假值,所以不执行i++,i是1,result是false
逻辑与运算符支持多个连用,此时会返回第一个布尔值为false的表达式的值;若所有表达式均为真值,则返回最后一个表达式的值。
console.log(true && 'foo' && '' && 4 && 'foo' && true);// ''
关系运算符的优先级高于逻辑与(&&)和逻辑或(||),因此类似表达式可直接书写,无需额外添加圆括号。
if(a+1==2 && b+2==3){
//Todo
}
逻辑与运算符可用于简化if结构,使代码更加紧凑。
if (a == b) {
doSomething();
}
// 等价于
(a == b) && doSomething();
在回调函数处理中,逻辑与运算符常用于确保参数存在后再执行调用,防止因未传参导致的错误。
//若没有给参数a传值,则a为默认的undefined,是假值,所以不执行a(),防止报错,如果给参数a传值,则执行函数a()
function fn(a){
if(a){
a();
}
}
//等价于
function fn(a){
a && a();
}
逻辑或运算符(||)
逻辑或
逻辑或运算符由两个竖线(||)表示,包含两个操作数。仅当两个操作数均为false时,运算结果才为false;否则返回true。
//逻辑或(||)的真值表
第一个操作数 第二个操作数 结果
true true true
true false true
false true true
false false false
与逻辑类似,逻辑或运算符也可应用于任意类型的操作数。当操作数非布尔类型时,运算结果未必是布尔值。
逻辑或运算同样具备短路特性:若第一个操作数足以决定最终结果,则不再对第二个操作数求值。
具体而言,若第一个操作数为true(真值),则无论第二个操作数为何值,结果均为true,并返回第一个操作数;若第一个操作数为false(假值),则结果取决于第二个操作数,并返回第二个操作数的值。
console.log('t' || '');//因为't'是真值,所以返回"t"
console.log('t' || 'f');//因为't'是真值,所以返回"t"
console.log('' || 'f');//因为''是假值,所以返回"f"
console.log('' || '');//因为''是假值,所以返回""
var i = 1;
var result = (true || i++);
console.log(result,i);//因为true是真值,所以不执行i++,result是true,i是1
var i = 1;
var result = (false || i++);
console.log(result,i);//因为false是假值,所以执行i++,i是2,result是1
逻辑或运算符同样支持多个连用,此时会返回第一个布尔值为true的表达式的值;若所有表达式均为假值,则返回最后一个表达式的值。
console.log(false || 0 || '' || 4 || 'foo' || true);// 4
逻辑或运算符常用于为变量设置默认值,当变量未赋值或为假值时,使用默认值替代。
//如果没有向参数p传入任何对象,则将该参数默认设置为空对象
function fn(p){
p = p || {};
}
以上即为JavaScript逻辑运算符的全面解析,涵盖逻辑非、逻辑与和逻辑或的核心机制与应用场景。