这个问题是不是一脸懵,往下看
在JavaScript中 == (“double equals”)被称为抽象相等比较("loose equality"),也叫做非严格相等。在比较两个值是否相等之前,两个被比较的值会转化为相同类型(等式两边都有可能被转化),转化完成之后再进性===的比较。
相等操作符的比较转化规律如下表:
B | B | B | B | B | B | ||
---|---|---|---|---|---|---|---|
Undefined | Null | Number | String | Boolean | Object | ||
A | Undefined | true | true | false | false | false | IsFalsy(B) |
A | Null | true | true | false | false | false | IsFalsy(B) |
A | Number | false | false | A === B | A === ToNumber(B) | A=== ToNumber(B) | A== ToPrimitive(B) |
A | String | false | false | ToNumber(A) === B | A === B | ToNumber(A) === ToNumber(B) | ToPrimitive(B) == A |
A | Boolean | false | false | ToNumber(A) === B | ToNumber(A) === ToNumber(B) | A === B | ToNumber(A) == ToPrimitive(B) |
A | Object | false | false | ToPrimitive(A) == B | ToPrimitive(A) == B | ToPrimitive(A) == ToNumber(B) | A === B |
在上面表格中,ToNumber(A)表示尝试将A转化为数字,“ToPrimitive(A)”尝试调用A的“toString”和“valueOf“方法将参数 A 转换为原始值(Primitive)。
一般而言,根据 ECMAScript 规范,所有的对象都与 undefined 和 null 不相等。但是大部分浏览器允许非常窄的一类对象(即,所有页面中的 document.all 对象),在某些情况下,充当效仿 undefined 的角色。相等操作符就是在这样的一个背景下。因此,IsFalsy(A) 方法的值为 true,当且仅当 A 效仿 undefined。在其他所有情况下,一个对象都不会等于 undefined或 null。
上面是mdn关于==的描述
以下是总结
1、undefined 和 null 之间相等 与其余都不相等(对象里的document.all除外不过基本遇不到)
2、number 与 string 比较 string先转成number然后再做对比,
number与boolean比较也是如此
number与object比较object先调用ToPrimitive方法转成原始值再做比较
3、String 与 boolean值比较 两者都转化为number类型
String与object比较object先调用ToPrimitive方法转成原始值再做比较
4、boolean与object比较object先调用ToPrimitive方法转成原始值,boolean转化为number 然后比较
下面我们来一条一条的试试
//num,undefined与各个类型比较
var num = 1;
var str = 'sd';
var bol = true;
var obj = {a:1}
var arr = [1]
undefined == null //true
undefined == num //false
undefined == str //false
undefined == bol//false
undefined == obj //false
null == num //false
null == str //false
null == bol//false
null == obj //false
//number与各个类型比较
1 == 'ss' //false 先将‘ss’转化成number 也就是 Number('ss') 得到的是NaN,NaN与任何东西都不想等
0 == ‘’ //true 先将‘’转化为number也就是Number('') 得到 0 所以为true
1==true//true, 将true转化为number类型,Boolean,true为1false为0 显而易见为true
//ToPrimitive方法是先调用object的valueOf,如果可以返回原始数字那么就返回,如果不能,则调用toString方法
1 == obj //false obj的valueOf返回的是对象本身不是原始值所以继续调用obj的toString方法得到'[object Object]'然后就是 1 == '[object Object]' 为false
//如果重写了valueOf那么表现就不一样了
Object.prototype.valueOf = function(){
return 1
}
1 == obj //true 因为这时候调用valueOf的时候返回了一个原始值,就不再调用toString方法
//string 与各个类型的比较
'sdf' == true//false 二者都要转化number类型,转化完以后 NaN === 1 为false
'sdf' == ['sdf'] //true 对象先调用valueOf方法返回的是数组本身非原始值,继续调用toString方法 得到字符串‘sdf’所以为true
true == obj // false 对象先调用valueOf方法返回的是数组本身非原始值,继续调用toString方法 得到字符 '[object Object]' 布尔值与字符串比较二者都转为number类型1===NaN 得到false
//Boolean值与各个类型比较
true == ['1'] // true 对象先调用valueOf方法返回的是数组本身非原始值,继续调用toString方法 得到字符 '1' 布尔值与字符串比较二者都转为number类型1===1 得到true
现在我们再来看这个题目
[] == ![] //首先右边有逻辑!这个优先级要高于== 先处理它 逻辑运算符!是将变量转变成boolean再取反
//那么第一步就是Boolean([]) 我们都知道Boolean 只有”“、0、-0、undefined、null、NaN、false这些返回false其余都是true,所以这里是true,取反得到false
[] == false
//上面我们知道了object与boolean比较,object调用valueOf,数组的valueOf是本身不是原始值,那么继续调用toString得到空字符串'',布尔值false转数字类型是0
'' == 0
//空字符串转数字类型得到0,所以
0 === 0 //true
好了,这次分享就到这里,想看具体的可移步MDN
https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Equality_comparisons_and_sameness
网友评论