运算符也被称为操作符,是用于实现赋值、比较和执行算术运算等功能的符号。JavaScript运算符主要包括:算术运算符、递增和递减运算符、赋值运算符、比较运算符、逻辑运算符、条件运算符等。表达式是由数字、运算符、变量等组成的有返回值的式子。
算术运算符主要用于处理加、减、乘、除和取模等数学运算,JavaScript常用算术运算符如表2-6所示。
表2-6 算术运算符
运算符“+”和“-”可以将其他类型转换为数值型,示例如下:
var age = "20"; console.log(typeof +age);// 输出:number
JavaScript采用IEEE754的双精度标准,在计算机内部存储数据的编码时,0.1在计算机内部不是精确的0.1,而是有舍入误差的。因此不能直接判断两个浮点数是否相等,可以根据业务对精度的要求用差值来间接判断,比如差值小于0.0005视为相等。示例如下:
console.log(0.1+0.2);// 输出:0.30000000000000004
递增运算符“++”和递减运算符“--”只接收一个操作数,根据操作数和运算符的相对位置不同,分为前递增、后递增、前递减、后递减四种情况,如表2-7所示。
表2-7 递增和递减运算符
【例2-1】递增运算
var num = 18; var res1 = ++ num; var age = 18; var res2 = age++; console.log("num的值是:"+num); console.log("age的值是:"+age); console.log("res1的值是:"+res1); console.log("res2的值是:"+res2);
例2-1在Chrome浏览器控制台中的输出结果,如图2-4所示。由输出结果可知,无论操作数在运算符的前面还是后面,通过自增运算后,操作数本身加1。区别主要体现在给其他变量赋值时,前递增运算会把操作数加1后的值赋给变量res1;后递增会先把操作数的值赋给变量res2,然后操作数加1。递减运算符和递增运算符的用法相同,不再赘述。
图2-4 【例2-1】输出结果
赋值运算符“=”把右侧表达式的值赋给左边的操作数。JavaScript赋值运算符,如表2-8所示。
表2-8 赋值运算符
比较运算符用于对两个操作数进行比较,比较的结果为真时返回true,结果为假时返回false。JavaScript比较运算符,如表2-9所示。
表2-9 比较运算符
【例2-2】比较运算符
console.log(1 == "1");// true。字符串“1”先转换为数字1再和1比较 console.log(1 === "1");// false。字符串“1”和数字1类型不同 console.log(NaN == NaN); // false。NaN不等于任何值 console.log(0.1 + 0.2 == 0.3); // false。由于精度问题0.1 + 0.2 不等于0.3 console.log(0.1 * 10 + 0.2 * 10 == 0.3 * 10); // true。转换为比较1+2 == 3 console.log(1 == true); // true。布尔型先转换为数字1再比较 console.log('21' < '15'); // false。字符串比较是按照每一位的Unicode码进行比较 console.log('21' < 15); // false。字符串“21”先转换为数字21再和15比较
例2-2在Chrome浏览器控制台中的输出结果,如图2-5所示。由输出结果可知,如果进行比较的两个操作数类型不同时,除了“===”和“!==”之外,其他操作符会自动将字符串类型数据转换为数字类型之后再比较。全等运算符“===”只有当两个操作数的类型和值均相等时,结果才为true。
图2-5 【例2-2】输出结果
逻辑运算符可以把两个或多个表达式连接成一个表达式,或使表达式的逻辑反转。JavaScript常用逻辑运算符,如表2-10所示。
表2-10 逻辑运算符
(1)逻辑&&运算符执行与运算,遵循以下两条规则。
①如果“&&”运算符左边的表达式为true或代表真的值,将继续进行右边表达式的计算,最终结果返回右边表达式的值。
②如果“&&”运算符左边的表达式为false或代表假的值,将不会进行右边表达式的计算,最终结果返回左边表达式的值。该规则也称为“短路”规则。
【例2-3】逻辑&&运算符
console.log(true && false); // 输出:false console.log(1 && 6); // 输出:6 console.log(0 && 6); // 输出:0 console.log(1 == 1 && 6); // 输出:6 console.log('a' && 'c'); // 输出:'c' console.log(null && 6); // 输出:null console.log(NaN && 6); // 输出:NaN console.log(undefined && 6); // 输出:undefined console.log(0 && 1 && 6 ); // 输出:0 console.log(1 && 2 && 3); // 输出:3
例2-3在Chrome浏览器控制台中的输出结果,如图2-6所示。由输出结果可知,逻辑与表达式的值既可以是布尔值,也可以不是布尔值。如果第一个表达式的值为真,则返回第二个表达式的值,如果第一个表达式的值为假,则返回第一个表达式的值。
图2-6 【例2-3】输出结果
提示: JavaScript程序中表达“1<x<9”的逻辑关系时,应写作“1<x && x<9”。“1<x<9”相当于“var temp=1<x; temp<9;”,其中“1<x”的返回值是true或false,“temp<9”中的比较运算符“<”会将布尔型temp转换为数字和9比较,true转换为1,false转换为0,因此无论x是多少,“temp < 9”恒成立,因此“1<x<9”返回结果始终都是true。
(2)逻辑“||”运算符执行或运算,遵循以下两条规则。
①如果“||”运算符左边的表达式为false或代表假的值,将继续进行右边表达式的计算,最终结果返回右边表达式的值。
②如果“||”运算符左边的表达式为true或代表真的值,将不会进行右边表达式的计算,最终结果返回左边表达式的值。
【例2-4】逻辑||运算符
console.log(true || false); // 输出:true console.log(1 || 6); // 输出:1 console.log(0 || 6); // 输出:6 console.log(1 == 1 || 6); // 输出:true console.log('a' || 'c'); // 输出:'a' console.log(null || 6); // 输出:6 console.log(NaN || 6); // 输出:6 console.log(undefined || 6); // 输出:6 console.log(0 || 1 || 6); // 输出:1 console.log(1 || 2 || 3); // 输出:1 var num = 0; 123 || num++;// 第一个表达式为真,num++不再执行 console.log(num);// 输出:0
例2-4在Chrome浏览器控制台中的输出结果,如图2-7所示。由输出结果可知,逻辑或表达式的值既可以是布尔值,也可以不是布尔值。如果第一个表达式的值为真,则返回第一个表达式的值,如果第一个表达式的值为假,则返回第二个表达式的值。
图2-7 【例2-4】输出结果
(3)逻辑“!”运算符执行取反运算,遵循以下两条规则。
①逻辑“!”运算符的操作数只有一个。
②逻辑“!”运算符在执行运算时,首先将操作数转换为布尔值,然后再对布尔值取反,返回true或false。示例如下:
console.log( !true ); // 输出:false console.log( !false ); // 输出:true console.log( !123 );// 输出:false,数字123转换为布尔值是true console.log( !null );// 输出:true,null转换为布尔值是false console.log( !undefined );// 输出:true,undefined转换为布尔值是false console.log( !NaN );// 输出:true,NaN转换为布尔值是false console.log( !!456 );// 输出:true,数字456转换为布尔值是true,两次取反后返回true
条件运算符是三元运算符,需要三个操作数。语法格式如下:
条件表达式?表达式1:表达式2
条件运算符根据条件表达式的真假返回不同的值,当条件表达式为真时,返回表达式1的值;当条件表达式为假时,返回表达式2的值。
【例2-5】输出两者中比较大的值
var a = 10; var b = 20; console.log(a > b ? a : b);// 输出:20
运算符优先级是指多个运算符放在一起进行运算时,优先使用哪个运算符进行运算。例如1+2*3表达式的结果是7,而不是9,因为乘法比加法的优先级高。
如果运算符的优先级相同,则需要按照结合方向来决定运算顺序。例如,乘法运算符是向左结合,所以2*3*4等价于(2*3)*4;赋值运算符“=”是向右结合,所以a=b=c等价于a=(b=c),即先把c的值赋给b,再把b的值赋给a。
本书建议通过增加小括号来明确显示运算符的优先级,从而增强程序的可读性。JavaScript运算符的优先级与结合性,如表2-11所示。
表2-11 运算符的优先级与结合性
【例2-6】运算符的优先级与结合性
// 根据优先级,先执行乘法再执行加法 console.log(1 + 5 * 2 ); // 根据优先级,先执行小括号里的1+5再和2相乘 console.log((1 + 5) * 2 ); // 根据优先级,先执行 3 > 5,再执行&&运算 console.log(3 > 5 && 2 < 7); // 根据优先级,先执行严格相等比较再赋值 var c = 2 === "2"; console.log(c); // 根据优先级,先执行取反,再执行&&运算,最后执行||运算 var d = !2 || 3 && 1; console.log(d);
例2-6在Chrome浏览器控制台中的输出结果,如图2-8所示。
图2-8 【例2-6】输出结果