JavaScript==比较的规则

JavaScript==比较的规则

一句话理解

==比较先把两侧的值转化为基本数据类型

也就是Number/String/布尔

如果两个基本数据类型不同

然后将基本数据类型转化为数字进行比较

如果相同直接比较值

看比较

"abc" == "abc"
  
都是字符串,类型相同,直接比较值,所以为 true
  
"1abc" == 1
  
不同类型 Number( "1abc" )为NaN
  
NaN == 1为 false
  
[] == []
  
两个对象,类型相同,不会转化,但是是两个不同的实例对象,所以为 false
  
[] == ![]
  
左侧为对象,右侧为布尔,所以进行转化
  
[]转化为基本数据类型使用toString方法,值为 ""
  
![]为 false ,可以通过Boolean(![])进行验证
  
false 转化为数字Number( false )为0
  
"" 转化为数字Number( "" )为0
  
所以相等
  
[] == true
  
不同类型
  
[]最终转化为数字为0
  
true 转化为数字为1
  
所以为 false
  
   
  
[] == false
  
同上,所以为 true
  
va b = function (){};
  
b == true
  
b为对象,转化使用toString
  
字符串是 "function(){}"
  
转化为Number,使用Number( "function(){}" )为NaN
  
所以为NaN == 1结果为 false
  
   
  
同样
  
b == false 也是
  
NaN == 0 结果还是 false
null ==undefined,undefined被当做基本类型, null 是对象, null 没有任何valueof和tostring的方法,所以转为基本类型为undefined
所以undefined==undefined

 

JS中简单类型与引用类型进行==比较的情况 
这种比较与是有规则的,并且可以用代码来验证JS内部的执行情况 
将一个简单类型(这里指除undefined与null的值)与一个对象比较时, 
先调用对象的valueOf方法,以期待返回一个标量,如果对象的valueOf方法返回的仍然是一个复合对象的话 
就接着调用对象的toString方法以期待返回一个标量,如果仍然没有返回标量的话,就判为不相等 
如果valueOf或toString方法之一返回一个标量,就用这个标量同==另一边的标量进行比较 

  1. var obj={};  
  2. alert(obj=="abc");//false  
  3. obj.toString=function () {  
  4.     return 'abc';  
  5. };  
  6. alert(obj=='abc');//这时就返回true了  
  7.   
  8. alert(obj==123);//false  
  9. obj.valueOf=function () {return 123};  
  10. alert(obj==123);//true!!!  
  11.   
  12. obj.valueOf=undefined;//先将这个方法清空掉,以免受上面的代码影响  
  13. alert(obj==true);//false  
  14. obj.valueOf=function () {  
  15.   return 1;//只要返回一个能转换成布尔值的标量就行了,1或true都行,都表示true  
  16. };  
  17. alert(obj==true);//true!!!!  


事实上还可以用下面的代码进行验证,将一个复合对象与标量进行比较时,总会先调用对象的valueOf, 
valueOf方法返回不是一个标量的话还会接着调用toString方法 

  1. var obj={  
  2.     toString:function () {  
  3.         alert('valueOf方法没有返回标量,我会被调用');  
  4.     },  
  5.     valueOf:function () {  
  6.         alert('我先被调用,Object的valueOf方法默认实现是返回对象自身');  
  7.     }  
  8. };  
  9. alert(1==obj);//可以看到执行次序  



那么讲了这么多,这和undefined!=false有什么关系呢? 
JS中的==对两边的对象进行比较时,undefined将被转换成数字,也就是说,undefined被看成基本值 
而又由于undefined转换成数字为NaN,所以将Number,String,Boolean这三种类型与undefined比较时,总是返回false 
而对于null,JS则将其当成对象来比较,即尝试调用null的valueOf与toString方法,再将返回的结果与另一个值进行比较,可以推断null==false返回false的原因是因为null的valueOf实现导致的 
由于null没有valueOf与toString方法,因此始终返回false 
自己写个个实例

function fru(){}
var a=new fru();
a.toString=function(){return 100;}//
//a.valueOf=function(){return this;}// 1   1去掉注释,2注释,则返回true

//a.valueOf=function(){return 111;}//2   2去掉注释,1注释,则返回false
alert(a==100);//true



ECMAScript规范是怎么说的? 
ECMAScript规范中指出,a与b进行比较,如果a与b是Number,String,Boolean这三种类型中的一种, 
并且a与b的类型不同,那么就将a与b都转换成数字再进行比较 
也就是说 

  1. var a="true";  
  2. var b=true;  
  3. alert(a==b);  
  4. //结果等同于下面的代码  
  5. alert(Number(a)===Number(b));  


而如果a是Number,String,Boolean这三种类型中的一种,而b是一个复合对象时(Object,Array等) 
则对b执行ToPrimitive操作(这步是JS解释器执行的) 
即 

  1. var a="abc";  
  2. var b={};  
  3. alert(a==b);  
  4. //上面的一行代码在JS解析时将被解释成  
  5. //a==ToPrimitive(b);  


而这个ToPrimitive方法的实现,正是依次去调用对象的valueOf,toString方法,直到其中一个方法返回一个基本值 
如果这两个方法没有返回基本值 ,那就认定不相等 

而当a和b都是复合对象时,就很简单,就看a和b是不是同一个对象的引用! 

而对于将undefined,null与其它类型进行比较的,则没具体说,只说了将 
任何基本类型与Boolean类型比较时,会将其转换成数字(与前面的规则一样) 


总结 
   Number,Boolean,String,Undefined这几种基本类型混合比较时,会将其转换成数字再进行比较 基本类型与复合对象进行比较时,

会先将复合对象转换成基本类型(依次调用valueOf与toString方法)再进行比较 undefined被当成基本类型,undefined转换成数字是NaN,

因此undefined与除null之外的其它类型值进行比较时始终返回false(注意NaN==NaN返回false) null被当成复合对象,由于null没有valueOf

与toString方法,因此和除了undefined之外的其它类型值进行比较时始终返回false 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值