只操作一个值的操作符叫一元操作符。
(1)递增递减操作符
无论使用前缀递增还是前缀递减操作符,变量的值都会在语句被求值之前改变。
let age = 29;
let another = --age+2;
console.log(age); //28
console.log(another); //30
后缀版和前缀版主要区别在于后缀版递增和递减在语句被求值后才发生。
let num1 = 2;
let num2 = 20;
let num3 = num1-- + num2; //22
let num4 = num1 + num2; //21
递增递减操作符可以用于任何值,意思是不限于整数、字符串、布尔值、浮点值甚至对象都可以,递增递减操作符遵循如下规则:
(2)一元加和一元减
如果将一元加应用到非数值,则会执行与使用Number()转型函数一样的类型转换:布尔值false和true转换为0和1,字符串根据特殊规则进行解析,对象会调用它们的valueOf()和/或toString()方法以得到可以转换的值。
let s1 = "01";
let s2 = "1.1";
let s3 = "z";
let b = false;
let o = {
valueOf() {
return -1;
}
};
s1 = +s1; //值变成数值1
s2 = +s2; //值变成数值1.1
s3 = +s3; //值变成NaN
b = +b; //值变成数值0
f = +f; //不变
o = +o; //值变成-1
布尔操作符一共有3个:逻辑非、逻辑与和逻辑或。
(1)逻辑非
逻辑非操作符由一个叹号(!)表示,可应用给ECMAScript中的任何值。这个操作符始终返回布尔值,无论应用到的是什么数据类型。逻辑非操作符首先将操作数转换为布尔值,然后再对其取反。逻辑非操作符会遵循如下规则:
逻辑非操作符也可以用于把任意值转换为布尔值。同时使用两个叹号(!!),相当于调用了转型函数Boolean()。
(2)逻辑与
逻辑与操作符由两个和号(&&)表示,应用到两个值。
第一个操作数 | 第二个操作数 | 结果 |
---|---|---|
true | true | true |
true | false | false |
false | true | false |
false | false | false |
逻辑与操作符可用于任何类型的操作数,不限于布尔值。如果有操作数不是布尔值,则逻辑与并不一定会返回布尔值,而是遵循如下规则:
逻辑与操作符是一种短路操作符,意思是如果第一个操作数决定了结果,那么永远不会对第二个操作数求值。对逻辑与操作符来说,如果第一个操作数是false,那么无论第二个操作数是什么值,结果也不可能等于true。
(3)逻辑或
逻辑或操作符由两个管道符(||)表示,遵循如下规则
第一个操作数 | 第二个操作数 | 结果 |
---|---|---|
true | true | true |
true | false | true |
false | true | true |
false | false | false |
与逻辑与类似,如果有一个操作数不是布尔值,那么逻辑或操作符也不一定返回布尔值,遵循如下原则:
同样与逻辑与类似,逻辑或操作符也具有短路的特性。只不过对逻辑或而言,第一个操作数求值为true,第二个操作数就不会再被求值了。
利用这个行为,可以避免给变量赋值null或undefined:
let myObject = preferredObject || backupObject;
在这个例子中,变量myObject会被赋予两个值中的一个。其中,preferredObject变量包含首选的值,backupObject变量包含备用的值。
ECMAScript定义了3个乘性操作符:乘法、除法、取模。如果乘性操作符有不是数值的操作数,则该操作数会在后台被使用Number()转型函数转换为数值。
乘法操作符
乘法操作符由一个星号(*)表示,可以用于计算两个数值的乘积。不过乘法操作符在处理特殊值时也有一些特殊的行为:
除法操作符
除法操作符由一个斜杠(/)表示,用于计算第一个操作数除以第二个操作数的商。跟乘法操作符一样,除法操作符针对特殊值也有一些特殊的行为:
取模操作符
取模(余数)操作符由一个百分比符号(%)表示,与其他乘性操作符一样,取模操作符对特殊值也有一些特殊的行为:
ECMAScript7新增了指数操作符,Math.pow()现在有了自己的操作符**,结果是一样的。
console.log(Math.pow(3, 2)); //9
console.log(3 ** 2); //9
(1)加性操作符(+)用于求两个数的和,如果两个操作数都是数值,加法操作符执行加法运算并根据如下规则返回结果:
如果有一个操作数是字符串,则要应用如下规则:
如果有任意操作数是对象、数值或布尔值,则调用他们的toString()方法以获取字符串,然后再应用前面的关于字符串规则。对于undefined和null,则调用String()函数,分别获取"undefined"和"null"。
let result1 = 5+5;
console.log(result1); //10
let result2 = 5+"5";
console.log(result2);//"55"
(2)减法操作符
减法操作符(-)也是使用很频繁的一种操作符,与加法操作符一样,减法操作符也有一组规则用于处理ECMAScript中不同类型之间的转换:
关系操作符执行比较两个值的操作,包括小于(<)、大于(>)、小于等于(<=)和大于等于(>=),这几个操作符都返回布尔值。
与ECMAScript中的其他操作符一样,在将它们应用到不同数据类型时也会发生类型转换和其他行为。
对字符串而言,关系操作符会比较字符串中对应字符的编码,而这些编码是数值。比较完之后,会返回布尔值。大写字母的编码都是小于小写字母的编码,因此以下这种情况就会发生:
let result = "Brick"<"alphabet"; //true
在这里字符串"Brick"被认为小于字符串"alphabet",因为字母B的编码是66,字母a的编码是97。要得到确实按照字母顺序比较的结果,就必须把两者都转换为相同的大小写形式(全大写或全小写)然后再比较:
let result = "Brick".toLowerCase<"alphabet".toLowerCase; //false
另一个比较奇怪的现象是在比较两个数值字符串的时候,如:
let result = "23"<"3"; //true
这里在比较字符串"23"和"3"时返回true。因为两个操作数都是字符串,所以会逐个比较它的字符编码(字符"2"的编码是50,而字符"3"的编码是51)。不过如果有一个操作数是数值,那么比较结果就对了:
let result = "23"<3; //false
只要数值和字符串比较,字符串就会先被转换为数值,然后再进行数值比较,对于数值字符串而言,这样能保证结果的正确,而如果字符串不能转换为数值呢?
let result = "a"<3;
因为"a"不能转换为任何有意义的值,所以只能转换为NaN,这里有个规则,即任何关系操作符在涉及比较NaN时都返回false:
let result1 = NaN<3; //false
let result2 = NaN>=3; //false
(1)等于和不等于
ECMAScript中的等于操作符用两个等于号(==)表示,如果操作数相等,则会返回true,不等于操作符用叹号等于(!=)表示,如果两个操作数不相等,则会返回true。这两个操作符都会先进行类型转换,再确定操作数是否相等:
在进行比较时,这两个操作符会遵循如下规则:
(2)全等和不全等
全等和不全等操作符与相等和不相等操作符类似,只不过它们在比较相等时不转换操作数。全等操作符由3个等号(===)表示,只有两个操作数在不转换的前提下相等才返回true:
let result1 = ("55"==55); //true
let result2 = ("55"===55); //false
不全等操作符用一个叹号和两个等号表示(!==),只有两个操作数在不转换的前提下不相等才返回true。
variable = boolean_expression?true_value:false_value;
上面的代码执行了条件赋值操作,即根据条件表达式boolean_expression的值决定将哪个值赋给变量variable。如果boolean_expression是true,则赋值true_value;如果boolean_expression是false,则赋值false_value。
逗号操作符可以用来在一条语句中执行多个操作:
let num1 = 1,num2 = 2,num3 = 3;