JS相等操作符比较规则

相等和不相等

如果两个数相等(==),则返回true

如果两个数不等(!=),则返回true

这两个操作符都会先转换操作数(通常称为强制转型),然后再比较它们的相等性

在转换不同的数据类型时,它们遵循下列基本规则:

  • 如果有一个操作数是布尔值,则在比较相等性之前先将其转换为数值——false转换为0,true转换为1
  • 如果一个操作数是字符串,另一个操作数是数值,在比较相等性之前先将字符串转换为数值
  • 对象或数组类型,优先调用valueOf方法,次之调用toString方法(重写的情况下),一般情况数组优先调用toString方法,得到的原始值按前面的规则比较
  • null与undefined相等
  • 要比较相等性之前,不能将null和undefined转换成其他任何值
  • 如果存在NaN,直接返回false
  • 如果两个操作数都是对象,要比较它们是否是同一个对象,如果两个操作数指向同一个对象,返回true,否则返回false

对于第三点的补充说明

因为数组的valueOf方法默认返回原数组,并不能进行比较,所以一般优先调用toString方法

一般的转换流程:

如果是原始值,直接返回原始值

不是原始值,调用该对象的ValueOf方法,如果结果是原始值,返回原始值

调用valueOf方法不是原始值,调用此对象的toString方法,如果结果是原始值,返回原始值

如果返回的不是原始值,抛出异常

而在==比较中我们经常需要把原始值转换成数值

一些例子

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
null == undefined //true
'NaN' == NaN //false
false == 0 //true
true == 2 //false
undefined == 0 //false
null == 0 //false

let a = {
valueOf:function(){
return '333';
}
}
let b = [444,333];
b.toString = function(){
return '333';
}
b.valueOf = function(){
return '444';
}
//如果说把b的两个方法都返回引用值,则在比较时会抛出异常
a=='333' //true 调用了valueOf方法
b=='333' //true 调用了toString方法
a==b //false 引用类型,指向不同的对象,返回false

//如果说a没有valueOf这个方法,只有toString方法
let a = {
toString(){
return '444';
}
}
a==444 //true 没有valueOf,则会调用toString,两者都有的情况下,还是优先valueOf
b==444 //true 只有一个则调用那一个,两者皆有优先valueOf

[]==false /*
false转换为0
[]的valueOf是原数组,不是原始值,所以调用toString转换成'',''再转换成0
所以返回true
*/

介绍下常见数据类型的valueOf与toString

toString返回的都是String类型

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
//number、null、undefined、string、boolean、obeject、symbol、bigint、
//function、date、array
let n = 1;
console.log(n.valueOf()); //Number 1
console.log(n.toString());

let str = 'abc';
console.log(str.valueOf()); //String abc
console.log(str.toString()); //abc

let bool = true;
console.log(bool.valueOf()); //Boolean true
console.log(bool.toString());

let obj = {}
console.log(obj.valueOf()); //Object 对象本身 {}
console.log(obj.toString()); //[object Object]

let sym = Symbol(str);
console.log(sym.valueOf()); //Symbol类型 Symbol(abc)
console.log(sym.toString()); //Symbol(abc)

let big = 1n;
console.log(big.valueOf()); //大数类型 1n
console.log(big.toString()); //1

let fn = function(){
console.log('我是一个函数')
}
console.log(fn.valueOf()); /*ƒ () {
console.log('我是一个函数')
} 返回函数本身*/
console.log(fn.toString());

let dat = new Date()
console.log(dat.valueOf()); //Number,存储的时间是从 1970 年 1 月 1 日午夜开始计的毫秒数 UTC 1634216654377
console.log(dat.toString()); //字符串日期 Thu Oct 14 2021 21:04:14 GMT+0800 (中国标准时间)

let arr = [1,2,3];
console.log(arr.valueOf()); //数组本身 (3) [1, 2, 3]
console.log(arr.toString()); //数组元素被转化成字符串,这些字符串由,分隔连接 1,2,3

全等和不全等

全等(===)

只有类型和值都一致时才为true

1
2
"55" == 55 //true
"55" === 55 //false 数据类型不同

不全等(!==)

1
55!=='55'  //true

JS相等操作符比较规则
https://blog-theta-ten.vercel.app/2021/10/13/JS相等操作符比较规则/
作者
Chen
发布于
2021年10月13日
许可协议