js 操作符详解
1. 一元操作符
只操作一个值的操作符叫一元操作符。
1. 递增/递减操作符
有两个版本:前缀版和后缀版。顾名思义,前缀版就是位于要操作的变量前头,后缀版就是位于要操作的变量后头。
前缀版:
前缀递增操作符会给数值加 1,把两个加号(++)放到变量前头即可:
let num = 29;
++num; // => num = num + 1; 得 num: 30
前缀递减操作符也类似,只不过是从一个数值减 1。使用前缀递减操作符,只要把两个减号(–)放到变量前头即可:
let num = 29;
--num; // => num= num - 1; 得 num: 28
前缀版在与其它操作混合时,先对变量进行递增/递减操作,再完成混合操作:
let num = 29;
let num1 = ++num + 2; // num = 30 num1 = 32
// => num = (num + 1) => num1 = num + 2;
// 意思是num先自增1, 然后将新值30 + 2赋值给num1
后缀版:
如果递增是唯一的操作,和前缀版没有区别:
let num = 29;
num++; // num: 30
注意: 后缀版与前缀版的主要区别在于,后缀版递增和递减在语句被求值后才发生:
let num1 = 2;
let num2 = 20;
let num3 = num1-- + num2;
let num4 = num1 + num2;
/*
num3 => 22 => num1--在和num2 相加的时候,
num1的值不变 2 + 20, 把22赋值给num3后,
num1 = num1 - 1 = 1num4 = 21 => 这是num1 = 1 num2 = 20
所以num4 = 21
*/
这 4 个操作符可以作用于任何值,意思是不限于整数——字符串、布尔值、浮点值,甚至对象都可以。递增和递减操作符遵循如下规则。
- 对于字符串,如果是有效的数值形式,则转换为数值再应用改变。变量类型从字符串变成数值;如果不是有效的数值形式,则将变量的值设置为 NaN 。变量类型从字符串变成数值;
- 对于布尔值,如果是 false,则转换为 0 再应用改变;如果是 true,则转换为 1 再应用改变;变量类型从布尔值变成数值;
- 对于浮点值,加 1 或减 1;
- 如果是对象,则调用其valueOf()方法取得可以操作的值。对得到的值应用上述规则。如果是 NaN,则调用 toString()并再次应用其他规则。变量类型从对象变成
数值。
let s1 = "2";
let s2 = "z";
let b = false;
let f = 1.1;
let obj = {valueOf() {return -1;}
};
s1++; // 数值3
s2++; // NaN
b++; // 数值1
f++; // 数值 2.1
obj++; // 会调用valueOf方法,返回-1 然后再加1 得 0
2. 一元加和减
一元加由一个加号(+)表示,放在变量前头,对数值没有任何影响:
let num = 25;
num = +num; // num => 25
如果将一元加应用到非数值,则会执行与使用Number()转型函数一样的类型转换:
布尔值 false和 true 转换为 0 和 1,字符串根据特殊规则进行解析,对象会调用它们的 valueOf()和/或toString()方法以得到可以转换的值:
let s1 = "01";
let s2 = "1.1";
let s3 = "z";
let b = false;
let f = 1.1;
let o = { valueOf() { return -1; }
};
s1 = +s1; // 值变成数值 1
s2 = +s2; // 值变成数值 1.1
s3 = +s3; // 值变成 NaN
b = +b; // 值变成数值 0
f = +f; // 不变,还是 1.1
o = +o; // 值变成数值-1
一元减由一个减号(-)表示,会执行与使用Number()转型函数一样的类型转换,放在变量前头,主要用于把数值变成负值,如把 1 转换为-1。(用法和一元+一样,转换为数值后取反)
2. 位操作符
这一部分小shy之前有发过专门介绍位操作符的博客,需要的可以看这篇:链接: https://blog.csdn.net/weixin_45112114/article/details/123135543?spm=1001.2014.3001.5501.
3. 布尔操作符(逻辑操作符)
1. 逻辑非(!)
这个操作符始终返回布尔值,无论应用到的是什么数据类型。逻辑非操作符首先将操作数转换为布尔值,然后再对其取反。
- 如果操作数是对象,则返回 false;
- 如果操作数是空字符串,则返回 true;
- 如果操作数是非空字符串,则返回 false;
- 如果操作数是数值 0,则返回 true;
- 如果操作数是非 0 数值(包括 Infinity),则返回 false;
- 如果操作数是 null,则返回 true;
- 如果操作数是 NaN,则返回 true;
- 如果操作数是 undefined,则返回 true。
console.log(!false); // true
console.log(!"blue"); // false
console.log(!0); // true
console.log(!NaN); // true
console.log(!""); // true
console.log(!12345); // false
小技巧:使用两个叹号(!!),相当于调用了转型函数Boolean()。
console.log(!!"blue"); // true
console.log(!!0); // false
console.log(!!NaN); // false
console.log(!!""); // false
console.log(!!12345); // true
2. 逻辑与(&&)
逻辑与操作符由两个和号(&&)表示,应用到两个值,逻辑与操作符遵循如下:
| 第一个操作数 | 第二个操作数 | 结果 |
|---|---|---|
| true | true | true |
| true | false | false |
| false | true | false |
| false | false | false |
let result = true && false; // false
逻辑与的特性是有假即假,全真为真,具有短路效果,如果&& 左边的表达式为false,就返回false,不会再判断&&右边的表达式了。
如果有操作数不是布尔值,则逻辑与并不一定会返回布尔值,而是遵循如下规则:
- 如果第一个操作数是对象,则返回第二个操作数;
- 如果第二个操作数是对象,则只有第一个操作数求值为 true 才会返回该对象;
- 如果两个操作数都是对象,则返回第二个操作数;
- 如果有一个操作数是 null,则返回 null;
- 如果有一个操作数是 NaN,则返回 NaN;
- 如果有一个操作数是 undefined,则返回 undefined。
let result = {} && 5; // 5 {}为真,取&&右边let result1 = 0 && 5; // 0 0为假, 取0,不走右边
3. 逻辑或(| |)
逻辑或操作符由两个管道符(| |)表示,逻辑或的特性是有真即假,全假为假,具有短路效果,如果| |左边的表达式为true,就返回true,不会再判断| |右边的表达式了。
| 第一个操作数 | 第二个操作数 | 结果 |
|---|---|---|
| true | true | true |
| true | false | true |
| false | true | true |
| false | false | false |
let result = true || false; // true
与逻辑与类似,如果有一个操作数不是布尔值,那么逻辑或操作符也不一定返回布尔值。它遵循如下规则:
- 如果第一个操作数是对象,则返回第一个操作数;
- 如果第一个操作数求值为 false,则返回第二个操作数;
- 如果两个操作数都是对象,则返回第一个操作数;
- 如果两个操作数都是 null,则返回 null;
- 如果两个操作数都是 NaN,则返回 NaN;
- 如果两个操作数都是 undefined,则返回 undefined。
let result = {} || 5; // {} {} 为真 取{} 不走右边let result1 = 0 || 5; // 5 0为假,取右边
4. 乘性操作符
ECMAScript 定义了 3 个乘性操作符:乘法、除法和取模。
1. 乘法操作符(*)
乘法操作符由一个星号(*)表示,可以用于计算两个数值的乘积:
let result = 5 * 6; // 30
不过,乘法操作符在处理特殊值时也有一些特殊的行为:
- 如果操作数都是数值,则执行常规的乘法运算,即两个正值相乘是正值,两个负值相乘也是正值,正负符号不同的值相乘得到负值。如果 ECMAScript 不能表示乘积,则返回 Infinity 或 -Infinity;
- 如果有任一操作数是 NaN,则返回 NaN;
- 如果是 Infinity 乘以 0,则返回 NaN;
- 如果是 Infinity 乘以非 0的有限数值,则根据第二个操作数的符号返回 Infinity 或-Infinity;
- 如果是 Infinity 乘以 Infinity,则返回 Infinity
- 如果有不是数值的操作数,则先在后台用 Number()将其转换为数值,然后再应用上述规则。
2. 除法操作符(/)
除法操作符由一个斜杠(/)表示,用于计算第一个操作数除以第二个操作数的商:
let result = 30 / 5; // 6
跟乘法操作符一样,除法操作符针对特殊值也有一些特殊的行为:
- 如果操作数都是数值,则执行常规的除法运算,即两个正值相除是正值,两个负值相除也是正值,符号不同的值相除得到负值。如果ECMAScript不能表示商,则返回Infinity或-Infinity;
- 如果有任一操作数是 NaN,则返回 NaN;
- 如果是 Infinity 除以 Infinity,则返回 NaN;
- 如果是 0 除以 0,则返回 NaN;
- 如果是非 0 的有限值除以 0,则根据第一个操作数的符号返回 Infinity 或-Infinity;
- 如果是 Infinity 除以任何数值,则根据第二个操作数的符号返回 Infinity 或-Infinity;
- 如果有不是数值的操作数,则先在后台用 Number()函数将其转换为数值,然后再应用上述规则。
3. 取模操作符(%)
取模(余数)操作符由一个百分比符号(%)表示:
let result = 26 % 5; // 1 余数为1
与其他乘性操作符一样,取模操作符对特殊值也有一些特殊的行为:
- 如果操作数是数值,则执行常规除法运算,返回余数;
- 如果被除数是无限值,除数是有限值,则返回 NaN;
- 如果被除数是有限值,除数是 0,则返回 NaN;
- 如果是 Infinity 除以 Infinity,则返回 NaN;
- 如果被除数是有限值,除数是无限值,则返回被除数;
- 如果被除数是 0,除数不是 0,则返回 0;
- 如果有不是数值的操作数,则先在后台用 Number()函数将其转换为数值,然后再应用上述规则。
5. 指数操作符(**)
ECMAScript 7 新增了指数操作符,Math.pow()现在有了自己的操作符**:
Math.pow(3, 2); // 3的平方: 9
3 ** 2; // 3的平方: 9
3 ** 3; // 3的三次方: 27
6. 加性操作符
1. 加法操作符(+)
加法操作符(+)用于求两个数的和:
let result = 1 + 2; // 3
如果两个操作数都是数值,加法操作符执行加法运算并根据如下规则返回结果:
- 如果有任一操作数是 NaN,则返回 NaN;
- 如果是 Infinity 加 Infinity,则返回 Infinity;
- 如果是-Infinity 加-Infinity,则返回-Infinity;
- 如果是 Infinity 加-Infinity,则返回 NaN;
- 如果是+0 加+0,则返回+0;
- 如果是-0 加+0,则返回+0;
- 如果是-0 加-0,则返回-0。
不过,如果有一个操作数是字符串,则要应用如下规则:
- 如果两个操作数都是字符串,则将第二个字符串拼接到第一个字符串后面;
- 如果只有一个操作数是字符串,则将另一个操作数转换为字符串,再将两个字符串拼接在一起;
- 如果有任一操作数是对象、数值或布尔值,则调用它们的 toString()方法以获取字符串,然后再应用前面的关于字符串的规则。对于 undefined 和 null,则调用 String()函数,分别获取"undefined"和"null"。
let result = 5 + 5; // 10let result1 = 5 + "5"; // "55"
2. 减法操作符(-)
减法操作符(-)也是使用很频繁的一种操作符:
let result = 2 - 1; // 1
与加法操作符一样,减法操作符也有一组规则用于处理 ECMAScript 中不同类型之间的转换:
- 如果两个操作数都是数值,则执行数学减法运算并返回结果;
- 如果有任一操作数是 NaN,则返回 NaN;
- 如果是 Infinity 减 Infinity,则返回 NaN;
- 如果是-Infinity 减-Infinity,则返回 NaN;
- 如果是 Infinity 减-Infinity,则返回 Infinity;
- 如果是-Infinity 减 Infinity,则返回-Infinity;
- 如果是+0 减+0,则返回+0;
- 如果是+0 减-0,则返回-0;
- 如果是-0 减-0,则返回+0;
- 如果有任一操作数是字符串、布尔值、null 或 undefined,则先在后台使用 Number()将其转换为数值,然后再根据前面的规则执行数学运算。如果转换结果是 NaN,则减法计算的结果是NaN;
- 如果有任一操作数是对象,则调用其 valueOf()方法取得表示它的数值。如果该值是 NaN,则减法计算的结果是 NaN。如果对象没有 valueOf()方法,则调用其 toString()方法,然后再将得到的字符串转换为数值。
let result1 = 1 - true; // true 被转换为 1,所以结果是 0let result2 = NaN - 1; // NaNlet result3 = 2 - 1; // 1let result4 = 5 - ""; // ""被转换为 0,所以结果是 5let result5 = 5 - "2"; // "2"被转换为 2,所以结果是 3let result6 = 5 - null; // null 被转换为 0,所以结果是 5
7. 关系操作符
关系操作符执行比较两个值的操作,包括小于(<)、大于(>)、小于等于(<=)和大于等于(>=),用法跟数学课上学的一样。这几个操作符都返回布尔值:
let result1 = 2 > 1; // true
let result2 = 2 < 1; // false
与 ECMAScript 中的其他操作符一样,在将它们应用到不同数据类型时也会发生类型转换和其他行为:
- 如果操作数都是数值,则执行数值比较;
- 如果操作数都是字符串,则逐个比较字符串中对应字符的编码;
- 如果有任一操作数是数值,则将另一个操作数转换为数值,执行数值比较;
- 如果有任一操作数是对象,则调用其 valueOf()方法,取得结果后再根据前面的规则执行比较;如果没有 valueOf()操作符,则调用 toString()方法,取得结果后再根据前面的规则执行比较;
- 如果有任一操作数是布尔值,则将其转换为数值再执行比较。
let result = "Brick" < "alphabet"; // true
/*
在这里,字符串"Brick"被认为小于字符串"alphabet",
因为字母 B 的编码是 66,字母 a 的编码是 97
*/// 可以转换字符串大小写形式比较
let result = "Brick".toLowerCase() < "alphabet".toLowerCase(); // false
let result = "23" < "3"; // true
/*
因为两个操作数都是字符串,所以会逐个比较它们的
字符编码(字符"2"的编码是 50,而字符"3"的编码是 51)
*/// 如果有一个操作数是数值,那么比较的结果就对了
let result = "23" < 3; // false
8. 关系操作符
1. 等于和不等于(==,!=)
ECMAScript 中的等于操作符用两个等于号(==)表示,如果操作数相等,则会返回 true。不等于操作符用叹号和等于号(!=)表示,如果两个操作数不相等,则会返回 true。这两个操作符都会先进行类型转换(通常称为强制类型转换)再确定操作数是否相等。
在转换操作数的类型时,相等和不相等操作符遵循如下规则:
- 如果任一操作数是布尔值,则将其转换为数值再比较是否相等。false 转换为 0,true 转换为 1;
- 如果一个操作数是字符串,另一个操作数是数值,则尝试将字符串转换为数值,再比较是否相等;
- 如果一个操作数是对象,另一个操作数不是,则调用对象的 valueOf()方法取得其原始值,再根据前面的规则进行比较;
在进行比较时,这两个操作符会遵循如下规则:
- null 和 undefined 相等;
- null 和 undefined 不能转换为其他类型的值再进行比较;
- 如果有任一操作数是 NaN,则相等操作符返回 false,不相等操作符返回 true。记住:即使两个操作数都是 NaN,相等操作符也返回 false,因为按照规则,NaN 不等于 NaN;
- 如果两个操作数都是对象,则比较它们是不是同一个对象。如果两个操作数都指向同一个对象,则相等操作符返回 true。否则,两者不相等。
下表总结了一些特殊情况及比较的结果:
| 第一个操作数 | 第二个操作数 |
|---|---|
| null == undefined | true |
| “NaN” == NaN | false |
| 5 == NaN | false |
| NaN == NaN | false |
| NaN != NaN | true |
| false == 0 | true |
| true == 1 | true |
| true == 2 | false |
| undefined == 0 | false |
| null == 0 | false |
| “5” == 5 | true |
2. 全等和不全等
全等和不全等操作符与相等和不相等操作符类似,只不过它们在比较相等时不转换操作数,全等操作符由 3 个等于号(===)表示。
相等操作符和全等操作符的区别在于:相等操作符会进行进行隐式转换,全等的条件是数据类型和值都要相等:
let result1 = ("55" == 55); // true, 转换后相等let result2 = ("55" === 55); // false 不相等,因为数据类型不同
不全等操作符用一个叹号和两个等于号(!==)表示,只有两个操作数在不转换的前提下不相等才返回 true:
let result1 = ("55" != 55); // false,转换后相等
let result2 = ("55" !== 55); // true,不相等,因为数据类型不同
9. 条件操作符(三元运算符)
result = (关系表达式) ? 表达式1 : 表达式2
根据关系表达式的值决定执行?后面哪个表达式,如果关系表达式的结果为true,则执行表达式1,如果为false,则执行表达式2。
let result1 = (5 > 1) ? true : false;
// 这里 5 > 1 表达式为true, 则将true赋值为result1 let result2 = (5 < 1) ? true : false;
// 这里 5 < 1 表达式为false, 则将false赋值为result2
10. 赋值操作符
简单赋值用等于号(=)表示,将=右边的值赋给=左边的变量:
let num = 10;
每个数学操作符以及其他一些操作符都有对应的复合赋值操作符:
- 乘后赋值(*=)
- 除后赋值(/=)
- 取模后赋值(%=)
- 加后赋值(+=)
- 减后赋值(-=)
- 左移后赋值(<<=)
- 右移后赋值(>>=)
- 无符号右移后赋值(>>>=)
本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!
