详解 JavaScript 中的相等(==)和全等(===),牵涉强制转换

重要的点

  • 相等不一定全等,全等一定等于,很好理解
  • 相等和不相等比较前会先转换操作数(强制转换,后面提到),全等和不全等则不会,所以这也是为什么使用全等运算符更安全的原因

相等的强制转换

  • 嫌麻烦可以直接跳过,看后面的踩坑部分
  • 强制转换不仅体现在相等运算符上,计算运算符也有,是个很复杂的点,此处不过多展开

规则

  • 如果有一个操作数是布尔值,则转换为数值:false => 0,true => 1
  • 如果一个是字符串,另一个是数值,则字符串转换为数值
  • 如果一个是对象,一个不是,则调用对象的valueOf()方法,用得到的基本类型按前面的规则比较
  • 特殊规则:
    • null == undefined
    • NaN不等于任何,包括它自己。可以这么理解,因为NaN的意思是 not a number,不是一个数,所以意味着它是不确定的,就像薛定谔的猫,在它确定之前它是没办法比较的,所以不相等
    • 如果两个都是对象,则是比较地址的相同性

原理

  • 在运算时,js会隐式调用 valueOf 和 toString 函数,这两函数是除 null 和 undefined 外其他数据类型原型链上共有的函数(意思就是其他类型都可以调用这两个函数)
  • 前者:返回最适合该对象类型的原始值;后者:将该对象的原始值转换为字符串
  • 一般,数值运算里,会优先调用前者;字符串运算里,会优先调用后者
  • 想更深入理解可以查看这篇有意思的文章toString()和valueOf()区别

经典面试题

  • 使a == 1 && a == 2 && a == 3为真,改写toString方法即可,valueOf同理
let a = {
	i: 1,
	// 定义类时可以重写toString/valueOf函数
	toString: function () {
		return a.i++
	}
}

a == 1 && a == 2 && a == 3 // true

踩坑实战

1 正负零
0 === -0 // true
1 / +0 // Infinity
1 / -0 // -Infinity
  • 0是有符号的,且正负零判定全等,但两者是不同的
  • 想判断出正负零得这样
function a (a, b) {
	if (a === b) return a !== 0 || 1 / a === 1 / b
	return false
}

console.log(a(-0, 0))
2 字符串
's' == new String('') // false,类型不同
new String('s') == new String('s') // false,地址不同
1 == '1' // true,强制转换
  • 如果用 new 创建number、string等,都是生成对象,比较地址
3 正则表达式
/1-9/ == /1-9/ // false,正则是对象,地址不同
'' + /1-9/ === '' + /1-9/ // 转换为字符串可比较内容是否相同(强制转换)
4 Date对象
let a = new Date()
let b = new Date()
+a === +b // true,加法使得a、b转换为数值(强制转换)
a.getTime() === b.getTime() // true
5 布尔值
var a = new Boolean('123');
var b = new Boolean('123');
+a === +b //true,同上理
6 NaN
// 自己和自己比较,不相等
NaN == NaN // flase

如果觉得对你有帮助的话,点个赞呗~

反正发文又不赚钱,交个朋友呗~

如需转载,请注明出处foolBirdd

  • 5
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值