运算符
1.简介
-
运算符也叫操作符。通过运算符可以对一个或多个值进行运算,并获取运算结果。
-
比如:typeof 就是运算符,可以来获得一个值的类型。它会将该值的类型以字符串的形式返回
-
+、*、/、(都是运算符,而(3+5)/2则是表达式。
2.优先级和结合性
- 从左往右先乘除后加减,有括号先算括号
| 优先级 | 运算符 | 说明 | 结合性 |
|---|---|---|---|
| 1 | []、.、() |
字段访问、数组索引、函数调用和表达式分组 | 从左向右 |
| 2 | ++ -- -~!delete new typeof void | 一元运算符、返回数据类型、对象创建、未定 义的值 | 从右向左 |
| 3 | *、/、% | 相乘、相除、求余数 | 从左向右 |
| 4 | +、- | 相加、相减、字符串串联 | 从左向右 |
| 5 | <<、>>、>>> | 左位移、右位移、无符号右移 | 从左向右 |
| 6 | <、<=、>、>=、instanceof | 小于、小于或等于、大于、大于或等于、是否 为特定类的实例 | 从左向右 |
| 7 | ==、!=、===、!== | 相等、不相等、全等,不全等 | 从左向右 |
| 8 | & | 按位“与” | 从左向右 |
| 9 | ^ | 按位“异或” | 从左向右 |
| 10 | | | 按位“或” | 从左向右 |
| 11 | && | 短路与(逻辑“与”) | 从左向右 |
| 12 | || | 短路或(逻辑“或”) | 从左向右 |
| 13 | ?: | 条件运算符 | 从右向左 |
| 14 | =、+=、-=、*=、/=、%=、&=、|=、^=、<、<=、>、>=、>>= | 混合赋值运算符 | 从右向左 |
| 15 | , | 多个计算 | 按优先级计算,然后从右向左 |
算术运算符
1.什么是算术运算符?
| 算术运算符 | |
|---|---|
| + | 加、字符串连接 |
| - | 减 |
| * | 乘 |
| / | 除 |
| % | 获取余数(取余) |
| () | 括号,优先级 |
2.算术运算符的优先级和结合性
* / %优先级要高于+ -- 无论是
+ - * / %都是左结合性(从左至右计算)
let result = 10 % 4;
console.log(result); >>2
3.注意点
- 当对非Number类型的值进行运算,会将这些值转换为Number然后再运算
result1 = true + 1; // 2 = 1 + 1
result2 = true + false; // 1 = 1 + 0
result3 = 1 + null; // 1 = 1 + 0
result4 = 100 - '1' // 99
- 任何值和NaN做运算的结果都是NaN
- 任何的值和字符串做加法运算,都会先转换为字符串,然后再做拼串操作
result1 = 1 + 2 + '3' // 33
result2 = '1' + 2 + 3; // 123
- 任何值做
-、*、/运算时都会自动转换为Number - 取模(取余)运算:m%n = 余数
- 如果m>n的, 那么就正常取余
- 如果m<n的, 那么结果就是m
- 如果n是0, 那么结果就是NaN
- 取余运算结果的正负性, 取决于m而不是n
let res = -10 % 3; // -1
赋值运算符
1.什么是赋值运算符?
- 就是将等号右边的值存储到等号左边的变量中
- 简单类型:
=;复杂类型:+= -= *= /= %=
2.优先级和结合性
- 赋值运算符的优先级低于算数运算符
- 右结合性(从右至左的计算)
- 左边只能放变量, 不能放常量
//由于算数运算符的优先级高于赋值运算符所以会先计算1 + 1, 然后再赋值给res
let res = 1 + 1;
// 由于赋值运算符的结合性是右结合性, 所以会先将3赋值给num2, 然后再将Num2中的值赋值给num1
let num1, num2;
num1 = num2 = 3;
自增自减运算符
1.什么是自增自减运算符?
- 自增运算符:
++ - 自减运算符:
-- - 用在变量中,不能用在常量/表达式中
2.自增
- 自增分成两种:
a++和++a。 - 对于一个变量自增以后,原变量的值会立即自增1。也就是说,无论是
a++还是++a,都会立即使原变量的值自增1。 - 要注意的是**:
a是变量,而a++和++a是**表达式 a++的值等于原变量的值(a自增前的值)++a的值等于新值 (a自增后的值)
3.自减:同上
var n1=10;
var n2=20;
var n = n1++; //n1 = 11 n1++ = 10
console.log('n='+n); // 10
console.log('n1='+n1); //11
n = ++n1 //n1 = 12 ++n1 =12
console.log('n='+n); //12
console.log('n1='+n1); //12
n = n2--;// n2=19 n2--=20
console.log('n='+n); //20
console.log('n2='+n2); //19
n = --n2; //n2=18 --n2 = 18
console.log('n='+n); //18
console.log('n2='+n2); //18
关系运算符
- 通过关系运算符可以比较两个值之间的大小关系,如果关系成立它会返回true,如果关系不成立则返回false
- 左结合性(从左至右的运算)
> < >= <=的优先级高于== != === !==
//正式因为关系运算符是左结合性, 所以不能利用关系运算符来判断区间
let res = 10 > 5 > 3; // true > 3; 1 > 3
let res = 10 <= 25 <= 20; // true <= 20 1 <= 20
| 关系运算符 | |
|---|---|
| > | 大于 |
| < | 小于 |
| >= | 大于或等于 |
| <= | 小于或等于 |
| == | 等于 |
| === | 全等于 |
| != | 不等于 |
| !== | 不全等于 |
- 对于非数值类型的数据, 会先转换成数值类型, 再进行判断
let res= 1 > true; // 1 > 1
let res= 1 > false; // 1 > 0
let res= 1 > null; // 1 > 0
let res= 1 > '10'; // 1 > 10
- 任何数据和NaN进行比较, 返回值都是false
console.log(10 <= 'hello'); //false
- 如果参与比较的都是字符串类型, 那么不会转换成数值类型再比较, 而是直接比较字符对应的Unicode编码
- 比较字符编码时,是一位一位进行比较。如果两位一样,则比较下一位,所以借用它可以来对英文进行排序
- 因此当我们在比较两个字符串型的数字时,一定一定要先转型,比如
parseInt()
// 比较两个字符串时,比较的是字符串的字符编码,所以可能会得到不可预期的结果
console.log('56'>'123'); //true
console.log('b' > 'a'); // 0062 > 0061
- ==符号
- 这个符号并不严谨,会将不同类型的东西,转为相同类型进行比较
- 只会判断取值
- undefined 衍生自 null,所以这两个值做相等判断时,会返回true
- NaN不和任何值相等,包括他本身
- 可以通过isNaN()函数来判断一个值是否是NaN
console.log('6'== 6); >>true
console.log(true == '1'); >>true
console.log(0 == -0); >>true
console.log(null == 0); >>false
console.log(undefined == null); >>true
console.log(NaN == NaN); >>false
console.log(isNaN(b)); >>false
- ===符号
- 如果要保证完全等于,我们就要用三个等号
===。 - 全等不会做类型转换
- 会同时判断取值和数据类型
==的反面是!=,===的反面是!==
- 如果要保证完全等于,我们就要用三个等号
console.log('6' === 6); >>false
console.log(6 === 6); >>true
逻辑运算符
-
分类
-
&&与(且):两个都为真,结果才为真。 -
||或:只要有一个是真,结果就是真。 -
!非:对一个布尔值进行取反。
-
-
注意事项
- 左结合性(从左至右的运算),
&&的优先级高于|| - 能参与逻辑运算的,都是布尔值
- 左结合性(从左至右的运算),
-
逻辑短路
- JS中的
&&属于短路的与,如果第一个值为false,则不会看第二个值 - JS中的
||属于短路的或,如果第一个值为true,则不会看第二个值
true && alert('hhh'); //hhh true || alert('hhh'); //true - JS中的
-
非布尔值运算
- 如果对非布尔值进行逻辑运算,则会先将其转换为布尔值,然后再操作, 但返回结果是原值
var result = 5 && 6; //true && true console.log(result); //6- 与运算的返回结果:(以两个非布尔值的运算为例)
- 如果第一个值为true,则必然返回第二个值(所以说,如果所有的值都为true,则返回的是最后一个值)
- 如果第一个值为false,则直接返回第一个值
- 或运算的返回结果:(以两个非布尔值的运算为例)
- 如果第一个值为true,则直接返回第一个值
- 如果第一个值为false,则返回第二个值
-
实际开发(做容错处理 )
// 当成功调用一个接口后,返回的数据为 result 对象。这个时候,我们用变量 a 来接收 result 里的图片资源。通常的写法是这样的:(这里我只是举个例子)
if (result.resultCode == 0) {
var a = result && result.data && result.data.imgUrl || 'http://img.smyhvae.com/20160401_01.jpg';
}
// 上方代码的意思是,获取返回结果中的result.data.imgUrl这个图片资源;如果返回结果中没有 result.data.imgUrl 这个字段,就用 http://img.smyhvae.com/20160401_01.jpg 作为兜底图片。这种写法,在实际开发中经常用到。
逗号运算符
- 逗号运算符
,- 在JavaScript中逗号运算符一般用于简化代码
- 左结合性(从左至右的运算)
- 优先级是所有运算符中最低的
- 逗号运算符也是一个运算符, 所以也有运算符结果,逗号运算符的运算符结果就是最后一个表达式的结果:
表达式1, 表达式2, 表达式3, ....;
// 利用逗号运算符同时定义多个变量
let a,b;
// 利用逗号运算符同时给多个变量赋值
a = 10,b = 5;
let res = ((1+1),(2+2),(3+3));
console.log(res); //6
三元运算符 / 条件运算符
- 语法: 条件表达式 ? 语句1 : 语句2;
- 如果该值为true,则执行语句1,并返回执行结果
- 如果该值为false,则执行语句2,并返回执行结果