先说一下黄色警告的问题:
大体意思就是:比较这两个值可能会导致意料之外的类型转换。
产生的问题:
那我们就很纠结了:为什么会导致意料之外的类型转换?哪来的类型转换?比较这两个值相不相等不就完事了吗?
解决步骤:
解决这一类问题最好的方法是追根溯源,即去找JavaScript的语法基础知识。
第一步、先来看一下JavaScript中关于判断两个值是否相等的语法:
==
两个等于号, 等于运算符, 也叫非严格相等比较, 又名宽松相等比较===
三个等于号, 恒等于运算符, 也叫严格相等比较Object.is
Object 的原型方法, ES6 的新特性;
第二步、分析三者的区别与联系:
==运算符在判断左右两个值是否相等时,它有一个附加的操作, 即数据类型转换——这也是它的优点, 也是它的缺点;
- 优点就是, 不用进行手动的类型转换, 引擎已经帮我们处理了;
- 缺点就是, 很容易造成混淆和逻辑混乱;
基于此,我们黄色警告的问题原因就找到了:==运算符的自动数据类型转换。
第三步、深究原因:
按理来说,自动类型转换不应该不出现任何警告、错误吗?那又为什么会出现意料之外的类型转换呢?
这个就是==运算符的默认规则问题了,简介如下:
当比较双方一个是对象, 一个是数字或者字符串时, 引擎会把对象转换成基本类型的数据,再对两者进行比较; 而对象转换成基本数据类型的方法, 就是执行对象的valueOf()
或者toString()
方法,当没有valueOf()方法
的时候会执行toString()方法。
举例如下:
示例一:
此时obj==1的值是true的,调用valueOf()方法,返回值为1
var obj = {
valueOf() {
console.log('valueOf: 1')
return 1
},
toString() {
console.log('toString: 1')
return '1'
}
}
console.log(obj == 1);//valueof()方法,true
//valueof: 1
示例二:
此时obj==1的值是true的,调用toString()方法,返回值为1
const obj = {
toString() {
console.log('toString: 1')
return 1
}
}
console.log(obj == 1);//true
// toString: 1
示例三:
此时obj==1的值是false的,调用valueOf()方法,返回值为2,因为2!=1,所以是false的。
const obj = {
valueOf() {
console.log('valueOf: 2')
return 2
},
toString() {
console.log('toString: 2')
return '2'
}
}
console.log(obj == 1)//false
//valueof: 2
再来看一下===运算符
===是恒等于运算符, 不会对左右两边的比较值进行类型转换, 类型不同必定不会相等
- 类型不同, 必定不相等
- 值不同必定不同
- 如果是
Number
类型
NaN === NaN // false
这个可以简单理解为java中的==和equals,两者有着异曲同工之妙。
Object.is
object.is大多数情况下是和===一样的,主要区别就在于Object.is(NaN,NaN)返回值是true,即NaN == NaN。