JavaScript中“&&”和“||”操做符的意义,深刻理解和使用场景

 1、概念html

与其余语言不一样,在js中,逻辑运算符能够返回任何类型的数据,不只仅是true和false。函数

&&和||的返回值是两个操做数的其中一个。即a&&b或者a||b返回的是要么是a,要么是b,而其余语言中返回的是true or false。优化

在js逻辑运算中,须要隐式的转换为boolean类型再来运算,转换规则为:spa

1. 对象、非number、非空string——>true.net

2. 0、""、null、false、undefined、NaN——>falsecode

具体见下表:htm

数据类型                
对象

转换为boolean后的值
NAN FALSE
null FALSE
undefined FALSE
Object TRUE
Function TRUE
0 FALSE 
非零的数字              TRUE
""(空字符串) FALSE
非空字符串              TRUE

所以:blog

a && b : 将a, b转换为Boolean类型, 再执行逻辑与, 若是结果是true返回b, false返回a
a || b : 将a, b转换为Boolean类型, 再执行逻辑或, 若是结果是false返回b, true返回第一个为true的值。
ip

逻辑&&和逻辑||还有一个短路原则:知道了前面第一个的结果就知道最后的输出

a&&b:左操做数为假值时,返回左操做数,不然返回右操做数。
a||b:左操做数为假值时,返回右操做数,不然返回左操做数。

只要“||”前面为false,无论“||”后面是true仍是false,都返回“||”后面的值。

只要“||”前面为true,无论“||”后面是true仍是false,都返回“||”前面的值。

只要“&&”前面是false,不管“&&”后面是true仍是false,结果都将返“&&”前面的值;

只要“&&”前面是true,不管“&&”后面是true仍是false,结果都将返“&&”后面的值;

一样对于多个操做数的状况:

a||b||c||d:若结果为true则返回第一个true值,若结果为false则返回最后一个操做数。eg:var a = “” || null || 3 || 2 -> var a = fasel || false || true || true 结果为true 则返回第一个true,便是3

a&&b&&c&&d:若结果为false则返回第一个false,若结果为true则返回最后一个操做数。eg:var b = 2&&null&&1&&0 -> var b = true&&false&&true&&false结果是false 则返回第一个false 便是null

2、理解

“&&”和“||”运算符都可以从三个不一样的层次来逐步理解:

以“&&”为例解释以下:

(1)最简单的第一层理解是,当操做数都是布尔值的时候,“&&”对两个值执行布尔与(AND)操做,只有在第一个操做数和第二个操做数都是true的时候,它才返回true。若是其中一个操做数是false,它返回false。

(2)“&&”的操做数并不必定是布尔值。因而对“&&”的第二层理解是,“&&”能够对真值和假值进行布尔与(AND)操做。若是两个操做数都是真值,那么返回一个真值;不然,至少一个操做数是假值的话,则返回一个假值。在JavaScript中任何但愿使用布尔值的地方,表达式和语句都会将其当作真值或假值来对待,所以实际上“&&”并不老是返回true和false。

(3)第三层理解,运算符首先计算左操做数的值,即首先计算“&&”左侧的表达式。若是计算结果是假值,那么整个表达式的结果必定也是假值,所以“&&”这时简单地返回左操做数的值,而并不会对右操做数进行计算。反过来说,若是左操做数是真值,那么整个表达式的结果则依赖于右操做数的值。若是右操做数是真值,那么整个表达式的值必定是真值;若是右操做数是假值,那么整个表达式的值必定是假值。

  理解以下例子对于理解“&&”可能不会去计算右操做数的状况相当重要,在如下示例代码中,变量p的值是null,而若是计算表达式p.x的话则会抛出一个类型错误异常。可是示例代码使用了“&&”的一种符合语言习惯的用法,所以只有在p为真值(不能是null或者undefined)的状况下才会计算p.x。反过来,咱们通常须要用某个对象p中的某个元素时,为了严谨也应该先对其是否存在进行判断。

var o = { x : 1 };
var p = null;
o && o.x // =>1:o 是真值,所以返回值为o.x
p && p.x //=>null: p是假值,所以将其返回,而并不去计算p.x

3、使用场景

1.||运算符最经常使用的方式是用来从一组备选表达式中选出第一个真值表达式,即从一系列值中获取第一个true值。

// 若是max_width已经定义了,直接使用它;不然在preferences对象中查找max_width;若是没有定义它,则使用一个写死的常量
var max = max_width || preferences.max_width || 500;

2.判断某个元素是否存在时:if(attr)写成if(!!attr)更加严谨。

!!的做用是把一个其余类型的变量转成的bool类型。eg:

typeof 5//"number"
typeof !!5//"boolean"

 3.对函数中的参数赋以默认值:a=a||"defaultValue";

 例如当a不存在或不合法时为其赋默认值,比起以下两种写法:

if(!a){
  a="defaultValue";
} 
if(a==null||a==""||a==undefined){
  a="defaultValue";
}

用||一句话就能够实现,简单又优雅:

a=a||"defaultValue"; 

4.利用&&的短路特性有条件的执行代码

(1)在回调中,常常这样写:callback&&callback(),先判断 callback 是否是存在,存在才执行,这样写更加严谨,若是直接写 callback(); 当callback不存在时代码就会报错。

(2)又或者常见的条件语句:if (a==b) stop();若是用&&来实现即为:(a==b)&&stop();

(3)判断某个对象存在再取值:p && p.x

应用举例:
如图:
假设对成长速度显示规定以下:
成长速度为5显示1个箭头;
成长速度为10显示2个箭头;
成长速度为12显示3个箭头;
成长速度为15显示4个箭头;
其余都显示都显示0个箭头。

(1)最容易想到也最常规的方法:if-else

var add_level = 0;
if(add_step == 5){
    add_level = 1;
}
else if(add_step == 10){
    add_level = 2;
}
else if(add_step == 12){
    add_level = 3;
}
else if(add_step == 15){
    add_level = 4;
}
else {
    add_level = 0;
} 

(2)switch方法:

var add_level = 0;
switch(add_step){
    case 5 : add_level = 1;
    break;
    case 10 : add_level = 2;
    break;
    case 12 : add_level = 3;
    break;
    case 15 : add_level = 4;
    break;
    default : add_level = 0;
    break; 
}

(3)而若是用&&和||就会超级简单:

var add_level = (add_step==5 && 1) || (add_step==10 && 2) || (add_step==12 && 3) || (add_step==15 && 4) || 0; 

优化为:

var add_level={'5':1,'10':2,'12':3,'15':4}[add_step] || 0; //对象取值有两种方式,一种object.key,一种是object[key],此处为法二

特别是若是需求改为:
成长速度为>12显示4个箭头;
成长速度为>10显示3个箭头;
成长速度为>5显示2个箭头;
成长速度为>0显示1个箭头;
成长速度为<=0显示0个箭头。
那么用switch实现起来也很麻烦了,而一样用&&和||只要以下便可。

var add_level = (add_step>12 && 4) || (add_step>10 && 3) || (add_step>5 && 2) || (add_step>0 && 1) || 0; 

 注:与&&和||不一样,!操做符的行为与C、Java等语言是一致的,只返回boolean值(true或false)。

参考:

http://www.cnblogs.com/yanayana/p/7079345.html

全面解析JavaScript中“&&”和“||”操做符(总结篇)

相关文章
相关标签/搜索