本来这篇应该是要写关于JavaScript的命名空间的,但是在查资料时,发现有些代码写得很牛逼,根本看不懂,用的还是最简单逻辑操作符,瞬间感觉自己逼格直线下降,所以这里插播广告,恶补一下逻辑运算。
JavaScript中的逻辑运算与其他语言的逻辑运算一样,有与或非三种,假如用于对布尔值进行逻辑运算,与其他语言并没有什么不同,也同样会有短路逻辑,优先级也是 非>与>或,这里就不再讨论了,主要是当逻辑运算符用于处理对象时,就需要好好聊聊了。
非操作(!)
/*
除了操作以下这些值返回true以外,其他全部返回false
*/
var a = !null; //操作null,返回true
var b = !undefined; //操作undefined,返回true
var c = !0; //操作数字0,返回true
var d = !false; //操作布尔值false,返回true
var e = !""; //操作空字符串,返回true
var f = !NaN; //操作NaN,返回true
除了以上示例中的操作会返回true以外,其他都会返回true。从上可以看出,进行非操作(!),返回的一定是一个true或false的布尔值。正是因为这个原因,为了保证if语句判断的条件一定是一个布尔值,会写成以下形式
if(!!a) ... //if的判断条件中用两个!保证返回的是布尔值
而 与操作(&&)和 或操作(||)就不见得了
与操作(&&)
/*布尔值为true的第一个操作对象时,直接返回第二个操作对象*/
var a = 1 && 2; //返回2
var b = "asdf" && function(){console.log("逻辑运算也可以返回函数对象")}; //返回这个函数对象
b(); //返回的函数对象也是可以直接调用的,和用其他方式定义的函数用法没有什么不同
/*布尔值为false的第一个操作对象时,直接返回这个为false的操作对象,这里就演示两个就可以了*/
var c = null && 2; //返回null
var d = NaN && function(){console.log("不管后面是什么都不返回了")}; //返回NaN
//d(); //因为d返回的是NaN,所以这里调用会报错
var e = 1 && 2 && null && 4; //1&&2返回2,2&&null返回null,null&&4返回null
总结下,发现以下规律:
- 布尔值为true的第一个操作对象时,直接返回第二个操作对象
- 布尔值为false的第一个操作对象时,直接返回这个为false的操作对象
或操作(||)
/*布尔值为true的第一个操作对象时,直接返回这个为true的操作对象*/
var a = 1 || 2; //返回1
var b = function(){console.log("逻辑运算也可以返回函数对象")} || false; //返回这个函数
b(); //返回的函数对象也是可以直接调用的,和用其他方式定义的函数用法没有什么不同
/*布尔值为false的第一个操作对象时,都是直接返回第二个对象,这里就演示两个就可以了*/
var c = null || 2; //返回2
var d = NaN || function(){console.log("第一个为false,所以返回这个函数")}; //返回这个函数
或操作(||)和与操作(&&)刚好相反:
- 布尔值为true的第一个操作对象时,直接返回这个为true的操作对象
- 布尔值为false的第一个操作对象时,都是直接返回第二个对象
优先级
非操作(!) > 与操作(&&) > 或操作(||)
- 注意:当逻辑运算符操作的不是布尔值,而是对象时,没有短路逻辑
代码精简
由于逻辑运算符(主要是与和或操作)可以操作对象,则可以利用这个特性来精简代码
var a = 1;
var b = 2;
(a<b) && (b-=5,a+=7);
console.log(a); //输出8
console.log(b); //输出-3
以上代码,先判断a
var a = 1;
var b = 2;
if(a<b){
b-=5;
a+=7;
}
console.log(a);
console.log(b);
网上很多帖子都复制了这个例子:
userNum && (ind += index,ind >= userNum && (ind -= userNum),ind < 0 && (ind === -2 && (ind = -1),ind += userNum),selLi.removeClass("on"),$(selLi[ind]).addClass("on"));
转换为大家熟悉的if语句块,则为:
if(userNum){
ind += index;
if (ind >= userNum) {
ind -= userNum
}
if(ind < 0){
if(ind === -2){
ind = -1;
}
ind += userNum;
}
selLi.removeClass("on");
$(selLi[ind]).addClass("on");
}
用逻辑操作符精简过的代码,看上去确实很高大上,但是这可读性极差了。所以,如果特别注重网络传输的文件大小,才考虑使用精简吧。
我们可以不用,但是一定要能看得懂,这才是重点。