携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第12天,点击查看活动详情
大家好!我是前端爬楼工程师🚹,一个野生程序员。好奇新技术,仰慕牛大佬。如果喜欢我的文章,可以关注➕点赞,为我注入能量,与我一同成长吧~
==允许在相等比较中进行强制类型转换,而===不允许;- 两者在性能上没有什么区别,需要强制类型转换的就用
==,否则===;
!! 错误的解释:===类型和值都相等,==值相等
==:抽象相等比较方法
// 特殊情况
NaN != NaN // true
+0 == -0 // true
类型相同
- 如果两个值的类型相等,就仅比较它们是否相等;
42 == 42 - 如果两个对象指向同一个值也视为相等,不发生强制类型转换;
var o = {name:1}
var a = o, b = o;
a==b // true
类型不同
字符串和数字之间的比较
42 == "42" // true
如果其中数字和字符串相比较,则将字符串进行ToNumber操作。
其他类型和布尔类型之间的比较
true == "42" // false
如果布尔类型比较,则对布尔类型进行ToNumber操作。
则变成了1 == "42"的比较,接着按照字符串和数字的规则,转换成
1 == 42,结果为false
那么false == "42"也是同样的道理,结果为false
"42"是一个真值,按道理来讲应该和 true 相等,因为这里不会发生ToBoolean的操作。
// bad code
var a == "42"
if(a == true){...}
if(a === true){...}
// good code
if(a){...}
if(!!a){...}
if(Boolean(a)){...}
null和undefined
null == undefined // true
undefined / null == 0 //false
undefined / null == false // false 其它类型和布尔类型进行比较的规则
// bad code
if(a == null || a == undefined){...}
// good code
if(a == null)
因为我们知道
null和undefined相等,这里只需要比较null或者undefined其中一个就行了
对象与非对象之间的比较
- 如果
Type(x)是字符串或数字,Type(y)是对象,比较x ==ToPrimitive(y)的结果。(ToPrimitive操作和ToNumber相同) - 如果
Type(x)是对象,Type(y)是字符串或数字,比较ToPrimitive(x)==y的结果。
[42] == "42" // true
[42]的valueOf()得到的不是基本类型,走toString()转换为"42",遵循字符串和数字规则,将字符串"42"进行ToNumber,比较42==42的,结果为true。
Object("abc") == "abc" // true
String("abc") == "abc" // true
Object("abc")和String("abc")通过ToPrimitive拆封,返回"abc",结果为true
// undefined null NaN
Object(undefined) == undefined // false
Object(null) == null // false
Object(NaN) == NaN // false
Object(null)和Object(undefined)返回一个{}。和undefined、null比较都为falseObject(NaN) 是一个Number类型,解封之后是NaN,NaN和NaN比较不相等
少见情况
Number.prototype.valueOf = function () {return 3}
new Number(2) === 3 // true
[] = ![] // true
ToBoolean规则转换[] == false, 布尔类型规则[] == 0对象规则"" == 0,字符串与数字比较规则0 == 0结果为true
有了以上规则不难看出:
[null] = "" // 结果:true 解释: [null] toString() 为 ""
[2] = 2 // 结果:true 解释:[2]toString()为"2" == 2 => 2 == 2
0 == "\n" //结果:true 解释: 空格组合都会ToNumber转换为 0
抽象关系比较
首先ToPrimitive操作,如果结果出现非字符串,还要双方进行ToNumber操作
- 字符串之间的比较: 按字母顺序比较
["42"] < 43 // true
首先
ToPrimitive将["42"]转换"42",然后按字母顺序比较。
var a = {b:42}
var b = {b:43}
a < b // false
a == b // false 解释:两个对象不叫不发生强制类型转换
a <= b // true
// 解释:在js里 a<=b 被处理 a > b 然后将结果反转,所以结果为true