《红宝书》 |操作符
《JavaScript高级程序设计-第四版》笔记
前言
操作符用于操作数据值,可用于字符串、数值、布尔值甚至是对象。包括一元操作符、位操作符、布尔操作符、乘性操作符、指数操作符、加性操作符、关系操作符、相等操作符、条件操作符、赋值操作符、逗号操作符
一元操作符
只操作一个值的操作符称为一元操作符。
递增/递减操作符
-
前缀:相当于加1;
let age=19; ++age; //30 相当于:age=age+1
变量的值在语句被求值前改变
let num1=29; let num2=--age+2; console.log(num1) //28 console.log(num2) //30
-
后缀:没变化;
let age=29 age++ //29
变量的值在语句被求值后改变
let num1=2; let num2=1; let num3=num1-- + num2; let num4=num1+num2 console.log(num3) //3 console.log(num4) //2
可作用于任何值
let str1="1"; let str2="a"; let b=false; let f=1.1; let o={ valueOf(){ return -1; } } str1++; //3 str2++; //NaN b++; //1 o--; //-2
一元加和减
-
一元
+
用于数值时对数值没有影响;
let num=11; num=+num; //11
用于非数值时相当于使用
Number()
;let str1="01"; let str2="1.1"; let str3="a"; let b=false; +str1; //1 +str2; //1.1 +str3; //NaN +b; //0
-
一元
-
主要用于把数值变成负数;
let num=11; num=-num; //-11
用于非数值时相当于使用
Number()
后再取负值;let str1="01"; let str2="1.1"; let str3="a"; let b=false; -str1; //-1 -str2; //-1.1 -str3; //NaN -b; //0
布尔操作符
逻辑非
由!
表示,可用于任何值。表示取反。
console.log(!false) //true
console.log(!true) //false
如果操作数不是布尔值,那么它首先会将操作数转换为布尔值(相当于调用了Boolean()
),接着再对其取反。
console.log(!{a:1}) //false
console.log(!null) //true
console.log(!"red") //false
console.log(!"") //true
console.log(!12) //false
console.log(!0) //true
console.log(!NaN) //true
同时使用两个感叹号!!
,相当于调用了转型函数Boolean()
。即相当于把值转换为布尔值。
console.log(!!"red") //true
console.log(!!0) //false
console.log(!!NaN) //false
console.log(!!"") //false
console.log(!!12) //true
逻辑与
由&&
表示,应用到两个任何值。只在同时两者都为true
的情况下才返回true
console.log(true && true) //true
console.log(true && false) //false
console.log(false && true) //false
console.log(false && false) //false
如果有操作数不是布尔值,遵循以下规则:
//1.如果第一个操作数是对象,返回第二个操作数
console.log({a:1} && true)// true
//2.如果第二个操作数是对象,则只有在第一个操作数求值为true时才会返回该对象
console.log(true && {a:1})// {a: 1}
console.log(false && {a:1})// false
//3.如果两个操作数都为对象,则返回第二个操作数
console.log({a:1} && {a:2})// {a: 2}
//4.如果有一个操作数是null,返回null
console.log(null && true)//null
//5.如果有一个操作数为NaN,返回NaN
console.log(NaN && true)//NaN
//6.如果有一个操作数是undefined,返回undefined
console.log(undefined && true)//undefined
逻辑与是一个短路操作符,即如果第一个操作数决定了结果,就不会对第二个操作数求值。举个例子,如果第一个操作数是false
,那么无论第二个操作数是什么,结果都是false
//第一个操作符为true,往后继续判断
let result=true && someUndeclaredVariable //报错:someUndeclaredVariable没有声明
//第一个操作符为false,就不会管后面的东西
let result=false && someUndeclaredVariable
console.log(result) //false
逻辑或
由||
表示,应用到两个任何值。只要其中一个为true
就会返回true
。
console.log(true || true) //true
console.log(true || false) //true
console.log(false || true) //true
console.log(false || false) //false
如果有一个操作数不是布尔值,那么它遵循以下规则:
//1.如果第一个操作数是对象,返回第一个操作数
console.log({a:1} || true)//{a:1}
//2.如果第一个操作数求值为false,返回第二个操作数
console.log(false || {a:1})//{a: 1}
//3.如果两个操作数都为对象,则返回第一个操作数
console.log({a:1} || {a:2})//{a: 1}
//4.如果两个操作数都是null,返回null
console.log(null || {a:1}) //{a:1}
console.log(null || null) //null
//5.如果两个操作数都是NaN,返回NaN
console.log(NaN || NaN)//NaN
//6.如果两个操作数都是undefined,返回undefined
console.log(undefined || undefined)//undefined
逻辑或同样是一个短路操作符。举个例子,如果第一个操作数是true
,那么无论第二个操作数是什么,结果都是true
//第一个操作符为false,往后继续判断
let result=false || someUndeclaredVariable //报错:someUndeclaredVariable没有声明
//第一个操作符为true,就不会管后面的东西
let result=true || someUndeclaredVariable
console.log(result) //true
【应用】利用这个行为,可以避免给变量赋值null
或undefined
。在下面例子中,prefferedObj
包含首选值,backupObj
为备选值。
let obj=prefferedObj || backupObj
乘性操作符
乘法操作符
由*
表示,用于计算两个数值的乘积。
console.log(20*3) //60
在处理特殊值时,遵循以下规则:
//1. 如果操作数都是数值,遵循常规的乘法运算
//2. 如果存在操作数为NaN,则返回NaN
//3. Infinity乘以0,返回NaN
//4. Infinity乘以非0的有限数值,则根据第二个操作数返回Infinity或-Infinity
//5. Infinity乘以Infinity,返回Infinity
//6. 如果有不是数值的操作数,则会默认先用Number()转换,接着遵循上述规则
console.log(20*NaN) //NaN
console.log(Infinity*0) //NaN
console.log(Infinity*1) //Infinity
console.log(Infinity*-1)//-Infinity
除法操作符
由/
表示,用于计算第一个操作数除以第二个操作数的商。
console.log(66/11) //6
console.log(66/10) //6.6
在处理特殊值时,遵循以下规则:
//1. 如果操作数都是数值,遵循常规的除法运算
//2. 如果存在操作数为NaN,返回NaN
//3. Infinity除以Infinity,返回NaN
//4. 0除以0,返回NaN
//5. 非0的有限数值除以0,则根据第一个操作数返回Infinity或-Infinity
//6. Infinity除以任何值,根据第二个操作数返回Infinity或-Infinity
//7. 如果有不是数值的操作数,则会默认先用Number()转换,接着遵循上述规则
console.log(20/NaN)//NaN
console.log(Infinity/Infinity)//NaN
console.log(0/0)//NaN
console.log(2/0)//Infinity
console.log(Infinity/2)//Infinity
取模操作符
由%
表示,求两个数的余数。
console.log(26%5)//1
在处理特殊值时,遵循以下规则:
//1. 如果操作数都是数值,遵循常规的除法运算,返回余数
//2. 如果被除数是无限数,除数是有限数,返回NaN
//3. 如果被除数是有限数,除数是无限数,返回被除数
//4. 如果被除数是有限数,除数是0,返回NaN
//5. Infinity除以Infinity,返回NaN
//6. 如果被除数是0,除数不是0,则返回被除数
//7. 如果有不是数值的操作数,则会默认先用Number()转换,接着遵循上述规则
console.log(Infinity%2)//NaN
console.log(2%Infinity)//2
console.log(2%0)//NaN
console.log(0%2)//0
指数操作符
由**
表示,与Math.pow()
计算的结果相同。
console.log(Math.pow(3,2))//9
console.log(3**2)//9
console.log(16**0.5)//4
加性操作符
加法操作符
由+
表示,求两个数的和。
console.log(1+1)//2
在处理特殊值时,遵循以下规则:
//1. 有任一操作数为NaN,返回NaN
//2. Infinity加Infinity,返回Infinity
//3. -Infinity加-Infinity,返回-Infinity
//4. Infinity加-Infinity,返回NaN
//5. +0加+0,返回+0
//6. -0加+0,返回+0
//7. -0加-0,返回-0
//8. 如果有不是数值且非字符串的操作数,则会默认先用Number()转换,再遵循以上规则
console.log(1+NaN)//NaN
console.log(1+true)//2
console.log(1+null)//1
console.log(1+undefined)//NaN
//9. 如果两个操作数都是字符串,进行拼接
//10. 如果只有一个操作数时字符串,则将另一个操作数转为字符串再拼接
console.log(1+NaN)//NaN
console.log("2"+"1")//"21"
console.log(1+"1")//"11"
【注意】加法运算是依次独立完成的
let num1=10
let num2=20
let message="10与20的和是"+num1+num2
console.log(message)//"10与20的和是1020"
//[解析]这是由于message先算:"10与20的和是"+num1,此时结果是:"10与20的和是10",是一个字符串,接在再去加一个num2,结果是字符串拼接的结果。
//[纠正]加上括号即可
let message="10与20的和是"+(num1+num2)
console.log(message)//"10与20的和是30"
减法操作符
由-
表示,求两个数的差
console.log(2-1)//1
在处理特殊值时,遵循以下规则:
//1. 有任一操作数为NaN,返回NaN
//2. Infinity减Infinity,返回NaN
//3. -Infinity减-Infinity,返回NaN
//4. Infinity减-Infinity,返回Infinity
//5. -Infinity减Infinity,返回-Infinity
//6. +0加+0,返回+0
//7. -0加+0,返回+0
//8. -0加-0,返回-0
//9. 如果仍一操作数是字符串、布尔值、null或undefined,则会默认先用Number()转换,再遵循以上规则
console.log(5-true)//4
console.log(NaN-1)//NaN
console.log(5-"")//5
console.log(5-null)//0
console.log(5-undefined)//NaN
关系操作符
用于比较两个值,包括>
、<
、>=
、<=
,返回布尔值。
console.log(5>3)//true
console.log(5<3)//false
遵循以下规则:
//1. 如果都是数值,比较数值
//2. 如果都是字符串,逐个比较字符串中首字符的编码,如果只有一个字符串,则先用Number()转换
//3. 如果仍一操作数是数值,则将另一操作数转为数值,再比较
//4. 如果仍一操作数是对象,则调用其valueOf()取得结果再依据上述比较,如果没有valueOf(),则调用toString()取得结果再比较
//5. 如果仍一操作数是布尔值,转换为数值后再比较
//6. 任何涉及NaN的比较都返回false
console.log("Brick"<"apple")//true,B的编码是66,a的编码是97
console.log("23"<"3")//true,"2"的编码是50,"3"的编码是51
console.log("a"<3)//false,"a"会转为NaN
相等操作符
用于判断两个变量是否相等。
等于与不等于
等于由==
表示;不等于由!=
表示。
//1. 如果任一操作数是布尔值,则将其转换为数值再作比较是否相等。false转0;true转1
console.log(false==0)//true
console.log(true==1)//true
console.log(true==2)//false
//2. 如果其中一个操作数是字符串,则先将字符串转为数值再比较
console.log("5"==5)//true
//3. 如果其中一个操作数是对象,则调用valueOf()方法取得其原始值,再根据上述规则比较
//4. null和undefined相等
//5. null和undefined不能转换为其他类型的值再比较
console.log(null==undefined)//true
console.log(undefined==0)//false
console.log(null==0)//false
//6. 如果仍一操作数是NaN,相等操作符返回false,不相等操作符返回true,即使两边都是NaN,相等操作符也返回false
console.log("NaN"==NaN)//false
console.log(NaN!=NaN)//true
console.log(5==NaN)//false
//7. 如果两个操作数都是对象,则比较它们是不是同一个对象,是的话返回true
全等和不全等
全等由===
表示,不全等由!==
表示。与“等于与不等于”的区别是它们在比较时不转换操作数。
console.log("55"==55)//true,转换后相等
console.log("55"===55)//false,不进行转换,由于数据类型不同所以不相等
console.log(null===undefined)//false,因为数据类型不同
console.log("55"!==55)//true
条件操作符
//即三元操作符,
variable=boolean_expression?true_value:false_value
变量=表达式?表达式为true时的值:表达式为false时的值
//[例子]
let grade=61
let result=grade>=60?"及格":"不及格"
console.log(result)//"及格"
赋值操作符
-
简单赋值由
=
表示let num=10
-
复合赋值使用乘性、加性、指数操作符或位操作符后跟
=
表示,包括:乘后赋值(*=
)、除后赋值(/=
)、取模后赋值(%=
)、加后赋值(+=
)、减后赋值(-=
)、指数后等于(**=
)let num=10 num+=10 //等同于:num=num+10 console.log(num)//20
逗号操作符
用来在一条语句中执行多个操作:
//[例子]声明多个变量
let num1=1,num2=2,num3=3;