最高半折刷qq各种业务和钻(家里人自己开的,尽管放心,大家多捧捧场)

sking7

导航

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 

posted on 2011-11-11 13:50  G.N&K  阅读(2537)  评论(2编辑  收藏  举报