本文介绍了JS中的运算符种类以及个别运算符作用和应用场景,前提需要你熟悉基本数据类型,了解隐式转换规则。
数据类型相关知识 JS-数据类型
隐式转换相关知识 JS-隐式转换
前置知识
-
基本数据类型:
String、Number、Boolean、Null、Undefined、Symbol、Bigint -
引用数据类型:
Object、ArrayFunctionDate、RegExp -
转换规则
-
其他转
Number:boolean转为0/1,undefined转为NaN,null转为0,string调用Number(),symbol不支持 -
其他转
String:加“”;number直接转 -
其他转
Boolean:nullundefined+0-0“”NaN转为false,其他都是true -
引用类型转基本类型
ToPrimitive(obj,type),一般type默认number,若obj是Date,type默认string。如果type是number,先调valueOf(),如果type是string,先调toString。ToPrimitive()一定会返回一个基本数据类型。
-
算数运算符
+ 、-、 * 、/、 % 、** 、++ 、--
+
- 两个作用
拼接、相加;相加涉及隐式转换。
- 两种类型
一元运算符、二元运算符,一元运算符优先级高。+'2' + +'3'=5
-
三种情景A+B
- 都是
String直接拼接。 - 一个是
String,将非String转为String再拼接。 - 都不是
String,转为Number再相加。
- 都是
-
计算机怎么相加的?0.1+0.2!==0.3
- 十进制转二进制:0.1和0.2都是1100循环
- js双精度保留53位,多余会舍去
- (a+b).toFixed(2)
-、 *、 /、 %、 ++、 --
- 操作数值超过数值表示范围,结果为Infinity 或 - Infinity。
- 操作数为NAN或Undefined,结果为NAN。
- 操作数不是Number类型,先调Number()转换,再运算。
- 操作数为对象,先对对象进行隐式转换,再运算。
逻辑运算符
&&、||
&&、||先对第一个操作数执行条件判断,若不是Boolean类型,就强制转换为Boolean类型,然后执行条件判断。&&、||返回的是其中一个操作数的值,不是条件判断结果,其实就是对两边的布尔值进行逻辑运算。交集和并集的关系。A||B:假设A是true,B是false,其实就是1||0,若第一个操作数为true返回第一个操作数的值,反之,第一个操作数为false,返回第二个操作数的值。总之,都假才假。A&&B:假设A是true,B是false,其实就是1&&0,若第一个操作数为true返回第二个操作数的值;反之第一个操作数为false,返回第一个操作数的值。假设A是对象,返回B,假设B是对象则要保证A是true才能返回B。假设A B都是对象,返回B,总之,一假才假。
!
- 操作数强制转为Boolean类型,取反。除了
null、NaN、undefined、""、0、false,其都是true。
位运算符
&、 |、 ~
-
&:一假就假,都真才真、|:都假才假、~:按位取反 -
&可以判断一个数的奇偶性
a&1==1是奇数 a&1==0是偶数
除了最低位是2^0,其余都是2的整数倍,所以最低位决定数的奇偶性。
1的二进制:最低位是1,其余位都是0 。1*2^0=1
|取整、比较是否相等
a|0==a
a|b==a两数相等
~取整
^
-
相同为0,相异为1;a^0=a; a^a=0; 满足交换律、结合律
-
应用:变量是数字,完成值交换,不加临时变量
- a=a^b
- b=b^a=b^a^b=a^b^b=a
- a=a^b=a^b^a=a^a^b=b
-
应用:查找数组中只出现一次的元素
全部元素的异或运算结果即为数组中只出现一次的数字。a^a=0
<<、>>、>>>
-
<<左移若干位,丢高位,低位补0 -
>>右移若干位,丢低位,正数高位补0,负数高位补1 -
>>>无符号右移若干位,丢低位,高位补0,符号位永远是0,值永远是正数,对于非负数>>和>>>结果相同。
比较运算符
==、=== 、!=、!==
-
===值和数据类型都相同才行,也就是内存中存储的地址相同;==值相同就相同。 -
==存在隐式转换会把两边数据类型转为一致,再比较值。- 两边都是基本数据类型,若是null与undefined返回true,若是其他基本数据类型和number类型比较,则将其他基本数据类型转为Number。
- 有一个是引用数据类型,则将引用数据类型转为基本数据类型再比较。链接,怎么转?
ToPrimitive(obj,type)
-
Object.is(a,b)与===类似,但是NaN等于NaN,+0和-0不相等 -
null==undefined为true -
null===undefined为false -
NaN===NaN为false,NaN不等于任何值,包括它本身。
<、 <=、 >、 >=
- 两个都是
Number,进行数值比较,有一个不是Number就强制转为Number。 - 两个都是
String, 则比较两个字符串对应的ascii码。 - 一个是
Object,要先对其进行隐式转换,转为基本数据类型。
赋值运算符
=、+=、-=、*=、/=、%=
基本数据类型赋值是栈中重新开辟一个存储空间,引用类型赋值的是栈中重新开辟一个存储空间,指向的堆内存空间的对应地址,指向堆中的地址是一样的
赋值的左操作数应该是一个引用记录,一个变量 var num = 10
引用两个操作:GetValue(V)对右边取值, PutValue(V,W)给左边设置值,第一个参数必须是引用
讲原理
条件运算符
条件?条件为真:条件为假
类型运算符
typeof、instanceof
其他运算符
.、,、()、void、delete、in、...
.
读取对象属性值,只能用在对象上,若点前面不是对象,先将其变为对象,调用完后再改回原来的类型。 通常用来判断this指向。
,
具备赋值操作GetValue(),返回第二个操作数。优先级比"="低。
()
(A)A可以是字面量或表达式,但是它不存在赋值操作,也就是不能不能用GetValue()取值 因为(delete aa)删除的是引用。
void
求表达式的值,或执行语句。 void值总是undefined。 a标签中return false阻止默认动作,与void(f())作用相同。
delete
-
基础类型,delete删除的是操作表达式的结果,值 字面量 目标不存在则直接返回true。
-
引用类型,删除的是引用。
-
返回true
- 删除对象属性或数组元素
- 删除成功
- 删除目标不存在
-
返回false
- 内置核心
- 客户端属性
- var 声明的变量,不能从全局或函数作用域删除
- let const声明的变量,不能从声明的作用域删除
- 不可枚举的属性 function 语句定义的函数
-
删除原型属性
delete Fn.prorotype.bar
in
a in b判断操作数a是否作为属性名存在于对象b中,是则返回true,不是则则返回false
...
扩展运算符 浅拷贝
综合案例
let name = "a"
const person = {
name: "person.name",
getName() {
return this.name
}
}
const getName = person.getName
console.log(getName())
console.log(person.getName())
console.log((person.getName)())
console.log((0,person.getName)())
- 涉及运算符:
=、()、,、. .运算符:读取对象属性值,只能用在对象上,若点前面不是对象,先变为对象,调用后再改回原来的类型。本质就是找this指向哪个对象,然后读取对象的属性或方法。this指向的是调用函数的对象- const getName = person.getName,若是引用类型,赋值操作会改变存储在内存中的地址。
- getName()没有this,默认指向全局,读取全局作用域的name,但是let和const声明的变量不会放在全局对象上,所以是undefined。
- person.getName()中this指向person,读取person里面的name。
- (person.getName)()没有发生取值赋值操作,()有没有都一样,赋值才会改变地址也就是this指向。这里this指向person。
- (0,person.getName)()中逗号是返回最后一个操作数据的值,产生赋值操作。优先级低于=,this指向全局对象,结果是undefined。
运算符测验
Infinity除、减Infinity、乘0都是NaN。
Infinity * 0 = NaN
Infinity * null = NaN
Infinity * undefined = NaN
Infinity / undefined = NaN
Infinity / Infinity = NaN
任何数 % undefined = NaN
任何数 % NaN = NaN
Infinity % 任何数 = NaN
有限大的数 % 0 = NaN
Infinity - Infinity = NaN
(-Infinity) - (-Infinity) = -NaN
-
Infinity加减任何有限值都是Infinity -
-Infinity加减任何值有限值都是-Infinity -
有限大的数 % Infinity = 有限大的数
Infinity - (-Infinity) = Infinity
Infinity - null = Infinity
Infinity * Infinity = Infinity
Infinity / 0 = Infinity
Infinity / null = Infinity
有限大的数 % Infinity = 有限大的数
0 % 除null、undefined、NaN任何数 = 0
数组原始值是""
对象原始值是[object,object]
[]+[]=''
[]+{}="[object,object]"
{}+[]=0
注意 [] {}转成boolean都是true;转成number,[]是0,{}是NaN。