浅谈逻辑运算符&&(与)和 ||(或)

Posted on 2017-03-30 15:20  冬游  阅读(3569)  评论(0编辑  收藏  举报

冬游有一群奇形怪状的小伙伴,总会问冬游一些奇形怪状的问题。

昨天冬游有一个叫周三胖(因崇拜某国领导人以及结合其个人特点所以姓周,号三胖⊙﹏⊙)的朋友,向冬游发了这么一张图片:

兄弟,上面那几句什么意思?

呔!三胖休得坑贫道。老衲不会!

大哥,我是真不会,求讲解?

%#@!#¥&

.....

经过三胖的一番软磨硬泡,死缠烂打,威逼利诱之后,我终于倒在三胖的花言巧语,甜言蜜语之中。

我balabala.....

吃瓜群众:我们瓜都吃完了你什么时候进入正题?

==============一脸懵逼的吃瓜群众分割线==============

好吧,我们进入正题,抛去上面的代码,我写下如下代码

 

1 function foo(){
2     var a = 1;  
3     var b = 2; 
4     var c = false;   
5     var d = true; 
6     console.log(c || (a = 1111),"a此刻的值:",a); 
7     console.log(d || (b = 2222),"b此刻的值:",b); 
8 }  
9 foo();

各位看官且说会输出神马?

好吧,浏览器输出如下

why???
且慢。我们再来修改一下foo函数: 

1 function foo(){
2     var a = 1;  
3     var b = 2;    
4     var c = false; 
5     var d = true;  
6     console.log(c && (a = 1111),"a此刻的值:",a); 
7     console.log(d && (b = 2222),"b此刻的值:",b);   
8 }   
9 foo(); 

 

 然后我们在浏览器中会看到如下:

ok,下面进入讲解部分:

&& 和 || 运算符在JavaScript中我更喜欢用初中物理中的电力并联串联来形容, || 运算符相当于并联线路图,而&&运算符则是串联,鉴于年代久远,老夫又出身文科转投工科,就不向各位理工高手看官介绍何为串联并联。

三胖:你分明就是不会!

去去去,盒饭拿好,赶紧回公司撸你代码!

咳咳,咱们继续。

|| 操作符会首先对第一个操作数进行判断,如果第一个为真,则直接返回第一个操作数的判断结果,对第二个操作数是啥不会进行判断运算,如果第一个为假值,则会去判断第二个操作数并对第二个操作数进行执行操作,而后返回执行操作判断值。所以对于||的说明我们可以用代码这么整理:

第一个操作数 || 第二个操作数

代码解释:  

1 if(第一个操作数){
2     return 第一个操作数; 
3 }
4 else{
5     return 第二个操作数;
6 }

 

进一步对foo中 c || (a = 1111) 套用上述解释就是:

 

1 if(c){ 
2     return c; 
3 } 
4 else{ 
5     return (a = 1111);      //此处在浏览器直接这么写会报错,建议先运算再取出返回值 
6 } 

 

同理 d || (b = 2222) 的套用就是

1 if(d){ 
2     return d; 
3 } 
4 else{ 
5     return (b = 2222);      //此处在浏览器直接这么写会报错,建议先运算再取出返回值 
6 } 

 

 

如此一来就会返回出上面的结果。

|| 运算符在我们处理事件兼容时广泛的被应用,比如:

 1 e = e || event; 

这所运用的思想就是这样一个思想,如果e为false或者undefined,则会把event赋值给e。

同时在除了在event中的应用外我们还应用在函数的传参上,比如:

1 function test(a){
2     a = a || 111;
3     console.log(a);
4 }

用此为函数形参指定默认参数,但是这么做其实是不安全的,比如当我调用test函数时我传入实参一个""(空字符串)或者传入实参0,此时浏览器会输出

在浏览器中会将""(空字符串)和0以及很多其它的假值进行隐式类型转换,所以单纯的进行这样一个判断是不严谨和不安全的,所以建议各位看官少用。

这是一个知识点。

三胖:甭废话,盒饭我快吃完了你才讲这么点?

我:哥屋恩...

各位看官别走,咱们继续(微笑脸)。

&& 运算符则和||正好相反,如果第一个操作数为真,则进行第二个操作数的判断运算,首先它会对第二个操作数进行运算,拿到第二个操作数的返回值,而后返回第二个操作数的返回值。如果第一个操作数为假,则进入第二个操作数的判断,直接返回false。

三胖:什么如果否则的,看的我都晕了。

我:

ko,咱们继续。

根据对||运算符的套路。我们继续将&&符转换为半代码半中文语言:

 

操作数一 && 操作数二

 

变身:    

1 if(第一个操作数){
2     return 第二个操作数;  
3 } 
4 else{ 
5     return false; 
6 }

 

继续对上面的 c && (a = 1111) 进行套用:   

1 if(c){
2     return (a = 1111);           //此处在浏览器直接这么写会报错,建议先运算再取出返回值 
3 }  
4 else{  
5     return false; 
6 }

 

 同理 d && (b = 2222) 的解释如下

 

1 if(d){
2     return (b = 2222);           //此处在浏览器直接这么写会报错,建议先运算再取出返回值 
3 }  
4 else{  
5     return false; 
6 }

 

如此输出结果如上。

三胖:嗯。(若有所思脸)

&&运算符一般用在不确定某一对象下是否有某一属性时的判断,比如我有如下代码

 

1 var list = {
2     obj : {},
3     array : [1,2,3,4,5]
4 }

 

 

 

在我不确定array是否为list下的属性时通常我们这么写  

1 if(list.hasOwnProperty("array")){
2     //dosomething
3 }
4 else{
5     //dosomething
6 }

 

结合&&符我们可以这么写 :

list.hasOwnProperty("array") && dosomething

 

对比以上两种写法,很明显在代码简洁性上,第二种写法完胜,但是在代码可读性上完败,两种方式都可以,这取决于个人习惯,我个人比较喜欢第二种写法。

我:三胖,回答我一个问题,回答完你就可以打卡下班了,知道逻辑运算符之间的优先级吗?

三胖:不知道。

我:哥屋恩....

三胖:得嘞(开心脸)。

滴,学生卡。

o(╯□╰)o

回来,你给我回来。

算了,各位看官,我们继续。

现在有如下代码: 

1 a = "hello";
2 b = false;
3 c = false;
4 console.log(a || b && c)

 

各位看官,再次猜测会输出什么。

按照正常从左道右的逻辑思维我们先拿到  a || b  的值,而后我们再与 c 进行&&运算,最后它会输出  false

然而,事与愿违。

浏览器最终输出----hello。

这里就体现了逻辑运算符之间的优先级关系,事实上浏览器在解析运算时是这样做的:

1 a || (b && c)

 

也就是先拿到 b && c 的值,而后再与 a 进行 || 运算,最后返回结果。

这也就是说在进行逻辑运算时 || 运算符的优先级低于 && 运算符。但是并不建议大家这么书写,这样会导致逻辑关系不明朗,代码可读性差的后果,所以各位看官在书写这样的代码时还是加上一个()为妙(手动滑稽)。

 

以上就是本次对逻辑运算符的浅谈随笔,如有不对,欢迎指出。文中我与三胖的日常大多实为剧情需要虚构而出,如有雷同实属巧合,语言风格非喜且轻喷。

我是冬游,一条游上岸的咸鱼,我的目标是翻个身,继续晒。