一元操作符
- 定义:只操作一个值的操作符
递增/递减操作符
-
前缀版
位于要操作的变量前面
变量的值会在语句被求值之前改变
前缀递增和前缀递减的优先级相等,所有从左向右依次求值
-
前缀递增操作符会给数值加1
let a = 20; ++a; // 上述代码等效于下面的代码 let a = 20; a = a+1;
-
前缀递减操作符给数值减1
let a = 20; --a; // 上述代码等效于下面的代码 let a = 20; a = a-1;
-
后缀版
位于要操作的变量后面
后缀版操作符在语句被求值之后才生效
-
例子
let n1 = 2; let n2 = 20; let n3 = n1-- + n2; let n4 = n1 + n2; console.log(n3); // n3的值是22,因为这里n3使用的是n1的原始值再加上n2 console.log(n4); // n4的值是21,因为这里的n1在上面计算n3的时候被减1了
-
这四个操作符可以作用于任何值
- 布尔值
- 如果是false,转成0再改变。此时变量类型变成数字
- 如果是true,转成1再改变。此时变量类型变成数字
- 浮点值
- 直接加1或减1
- 对象
- 调用其valueOf()方法取得可以操作的值
- 对这个可以操作的值应用上述规则
- 如果是NaN就调用toString()并应用上述规则
- 变量类型从对象变成数字
- 字符串
- 如果是有效的数值形式,转成数字再改变。此时变量类型从字符串变成数字
- 如果不是有效的数值形式,就将变量的值设置为NaN。此时变量类型从字符串变成数字
- 布尔值
-
例子
let str1 = "2"; let str2 = "a"; let f = false; let a = 1.1; let obj = { valueOf(){ return -1; } }; console.log(++str1); // 3 console.log(str1++); // 2 console.log(str2++); // NaN console.log(++str2); // NaN console.log(f++); // 0 console.log(++f); // 1 console.log(a++); // 1.1 console.log(++a); // 2.1 console.log(obj--); // -1 console.log(++obj); // 0
一元加和减
- 数学上的加法和减法
- 如果应用到非数值上,
- 布尔值:false转成0,true转成1
- 字符串:根据特殊规则进行解析
- 对象:调用valueOf()方法,toString()方法
位操作符
- 主要用于操作内存中表示数据的比特(位)
- 有符号整数使用32位表示,其中前31位表示整数值,第32位是符号位(即从左数第一位是符号位),表示符号(0表示正,1表示负)
- 正值以真正的二进制格式存储,即31位中每一位都表示2的幂,从右向左数,第一位是2的零次方,第二位是2的一次方,以此类推,如果一个位是空的,就以0填充,表示忽略不计
- 负值以一种称为二补数(补码)的二进制编码存储,补码计算步骤如下:
- 确定其绝对值的二进制表示(比如对于-13,先确定13的二进制)
- 找到每一位数字的一补数(反码),即每个0都变成1,每个1都变成0
- 给每一个反码都加上1
按位非
按位非操作符使用波浪符(~)表示
按位非的作用是返回数字的一补数(反码)
最终效果是对数字取反然后减1
-
例子
let n1 = 23; let n2 = ~n1; console.log(n1.toString(2)); // 二进制是10111 console.log(n2.toString(2)); // 二进制是-11000 console.log(n2); // -24
按位与
按位与操作符使用和号(&)表示
有两个操作数,将两个操作数的每一位对齐,然后按照指定的规则对每一位进行相应的操作
-
规则
第一个数字的位 第二个数字的位 结果 1 1 1 1 0 0 0 1 0 0 0 0 总的来说就是:全1得1,有0得0
-
例子
let n1 = 25; let n2 = 3; console.log(n1.toString(2)); // 25的二进制是11001 console.log(n2.toString(2)); // 3的二进制是11 console.log(n1&n2); // 结果是1
- 可以看出,25和3的二进制表示中,只有第0位上两个数都是1,其他都是0
按位或
按位或操作符用管道符(|)表示
有两个操作数,将两个操作数的每一位对齐,然后按照指定的规则对每一位进行相应的操作
-
规则
第一个数字的位 第二个数字的位 结果 1 1 1 1 0 1 0 1 1 0 0 0 总的来说就是:有1得1,全0得0
-
例子
let n1 = 25; let n2 = 3; console.log(n1.toString(2)); // 25的二进制是11001 console.log(n2.toString(2)); // 3的二进制是11 console.log(n1|n2); // 结果是27
- 将25和3的二进制表示对齐之后,得到的二进制结果是11011,转成十进制就是27
按位异或
按位异或用脱字符(^)表示
有两个操作数,将两个操作数的每一位对齐,然后按照指定的规则对每一位进行相应的操作
-
规则
第一个数字的位 第二个数字的位 第二个数字的位 1 1 0 1 0 1 0 1 1 0 0 0 总的来说就是:相同得0,不同得1
-
例子
let n1 = 25; let n2 = 3; console.log(n1.toString(2)); // 25的二进制是11001 console.log(n2.toString(2)); // 3的二进制是11 console.log(n1^n2); // 结果是26
将25和3的二进制表示对齐之后,按照规则得到的二进制结果是11010,转成十进制就是26
左移
左移操作符使用两个小于号表示
会按照指定的位数将数字的所有位向左移动
移动之后,数字右端会空出位数,然后以0填充这些空位
左移会保留它所操作数值的符号
-
例子
let n1 = 2; let n2 = n1 << 5; console.log(n2.toString(2)); // 二进制表示结果是:1000000 console.log(n2); // 转成十进制就是64
有符号右移
- 有符号右移使用两个大于号表示,会将数字的所有32位往右边移动,同时保留符号
- 右移之后会出现空位,但是空位出现在左侧,而且在符号位之后,会使用符号位的值来填充这些空位
无符号右移
- 无符号右移使用三个大于号表示,会将数字的所有32位向右移
- 对于正数,无符号右移和有符号右移结果一样
- 对于负数,无符号右移会给空位补0,不考虑符号位
- 此时会将负数的二进制表示当成正数的二进制表示来处理
布尔操作符
逻辑非
- 逻辑非操作符使用感叹号表示,无论应用到什么数据类型,都是先将操作数转成布尔值,然后取反
- 规则
- 操作数是对象,返回false
- 操作数是空字符串,返回true
- 操作数是非空字符串,返回false
- 操作数是0,返回true
- 操作数是非0数字(包括Infinity),返回false
- 操作数是null,返回true
- 操作数是NaN,返回true
- 操作数是undefined,返回true
- 同时使用两个感叹号,也可以将任意值转成布尔值,第一个感叹号会将操作数转成布尔值,第二个感叹号对这个布尔值取反,从而得出操作数真正对应的布尔值
逻辑与
- 逻辑与操作符用两个和号(&&)表示
- 对两个操作数进行操作
- 规则:两个都是true就返回true,有一个是false就返回false
- 逻辑与是一种短路操作符,即如果第一个操作数决定了结果,那么永远不会对第二个操作数求值
- 可以应用于任何类型的操作数,如果有操作数不是布尔值,那么会遵循一定的规则
- 如果第一个操作数是对象,那么返回第二个操作数
- 如果第二个操作数是对象,那么只有第一个操作数求值为true才会返回该对象
- 如果两个操作数都是对象,返回第二个操作数
- 如果有一个操作数是null,返回null
- 如果有一个操作数是NaN,返回NaN
- 如果有一个操作数是undefined,返回undefined
逻辑或
- 逻辑或操作符用两个管道号(||)表示
- 规则:两个都是false就返回false,有一个是true就返回true
- 逻辑或是一种短路操作符,如果第一操作数求值是true,第二个操作数就不会被求值了
- 可以应用于任何类型的操作数,如果有操作数不是布尔值,那么会遵循一定的规则
- 如果第一个操作数是对象,那么返回第一个操作数
- 如果第一个操作数求值是false,那么返回第二个操作数
- 如果两个操作数都是对象,返回第一个操作数
- 如果两个操作数都是null,返回null
- 如果两个操作数都是NaN,返回NaN
- 如果两个操作数都是undefined,返回undefined
乘性操作符
乘法操作符
- 星号表示乘法操作符,计算乘积
- 特殊规则
- 如果操作数都是数字,执行常规的乘法运算,如果不能表示乘积,就返回Infinity或-Infinity
- 任意一个操作数是NaN,返回NaN
- Infinity乘以0,返回NaN
- Infinity乘以非0的有限数值,根据第二个操作数的返回确定返回Infinity或-Infinity
- 如果是Infinity乘以Infinity,返回Infinity
- 如果有不是数值的操作符,那么先在后台使用Number()将其转换为数字,再应用上述规则
除法操作符
- 一个斜杠表示触发操作符
- 特殊规则
- 如果操作数都是数字,执行常规的除法运算,如果不能表示商,就返回Infinity或-Infinity
- 任意一个操作数是NaN,返回NaN
- Infinity除以Infinity,返回NaN
- 0除以0,返回NaN
- 非0的有限值除以0,根据第一个操作数的符号返回Infinity或-Infinity
- Infinity除以任何数值,根据第二个操作数的符号返回Infinity或-Infinity
- 如果有不是数值的操作符,那么先在后台使用Number()将其转换为数字,再应用上述规则
取模操作符
- 一个百分比符号表示取模操作符
- 特殊规则
- 如果操作数都是数字,执行常规的除法运算,返回余数
- 如果被除数是无限值,除数是有限值,返回NaN
- 如果被除数是无限值,除数0,返回NaN
- Infinity除以Infinity,返回NaN
- 如果被除数是有限值,除数无限值,返回被除数
- 如果被除数是0,除数不是0,返回0
- 如果有不是数值的操作符,那么先在后台使用Number()将其转换为数字,再应用上述规则
指数操作符
两个乘号表示指数操作符
效果和Math.pow()一样
-
例子
console.log(Math.pow(3,2)); console.log(3**2);
加性操作符
加法操作符
- 使用加号表示
- 特殊规则
- 任一操作数是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
减法操作符
- 使用减号表示
- 特殊规则
- 任一操作数是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()方法,将得到的字符串转成数字
关系操作符
- 用来比较两个值的操作,包括小于,大于,小于等于,大于等于,都返回布尔值
- 特殊规则
- 如果操作数都是数字,执行数字比较
- 如果操作数是字符串,则逐个比较字符串中对应字符串的编码
- 如果任一操作数是数字,则将另一个操作数转成数字,执行数字比较
- 如果任一操作数是对象
- 调用其valueOf()方法,取得结果后再根据前面的规则执行比较
- 如果没有valueOf()方法,调用toString()方法,取得结果后再根据前面的规则执行比较
- 如果任一操作数是布尔值,转成数字再比较
- 任何关系操作符在涉及到NaN的比较时,都返回false
相等操作符
等于和不等于
- 使用两个等于号表示等于操作符
- 使用感叹号和等于号表示不等于操作符
- 这两个操作符在比较之前会先进行类型转换(强制类型转换)
- 转换类型的规则
- 如果任何一个操作数是布尔值,则将它转成数字之后再和另一个操作数比较(false转成0,true转成1)
- 如果一个操作数是字符串,另一个是数字,那么就尝试将字符串转成数字再比较
- 如果一个操作数是对象,另一个不是,就调用对象的valueOf()方法取其原始值,然后再根据前面的规则比较
- 比较规则
- null和undefined相等
- null和undefined不能转换成其他类型的值
- 如果有任何一个操作数是NaN,则相等操作符返回false,不相等操作符返回true(就算两个都是NaN也是这个结果)
- 如果两个操作数都是对象,那么就比较它们是不是同一个对象,如果它们两个都指向同一个对象,相等操作符返回true
全等和不全等
-
全等操作符
三个等号表示
-
只有两个操作数在不转换的情况下相等才返回true
let result1 = ("55"==55); // true,等于操作符先转换,转换之后比较是相等的 let result2 = ("55"===55); // false,全等操作符不能转换,比较是不相等的
-
不全等操作符
用一个叹号和两个等于号表示
-
只有两个操作数在不转换的情况下不相等才返回true
let result1 = ("55"!=55); // false,不等于操作符先转换,转换之后比较是相等的 let result2 = ("55"!==55); // true,不全等操作符不能转换,比较是不相等的
注意:null==undefined的结果是true,但是null===undefined的结果是false,因为它们类型不同
条件操作符
-
语法格式
变量名 = 判断表达式 ? 表达式成立的赋值 : 表达式不成立的赋值;
-
例子
v1 = (n1 > n2) ? n1:n2; // 这里表示如果n1大于n2,就把n1的值赋给v1,否则就把n2的值赋给v1
赋值操作符
-
简单赋值
- 使用等号,将右边的值赋给左边的变量
-
复合赋值
-
使用乘性,加性或位操作符和等号结合
let n1 = 10; n1 += 10;
-
逗号操作符
-
可以在一条语句中执行多个操作
let n1 = 1,n2 = 2,n3 = 3;
-
可以在一条语句中同时声明多个变量
let num1 = (5,4,1,0); // 最后num1的值是0,因为0是表达式中最后一项