一句话理解
==比较先把两侧的值转化为基本数据类型
也就是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方法之一返回一个标量,就用这个标量同==另一边的标量进行比较
- var obj={};
- alert(obj=="abc");//false
- obj.toString=function () {
- return 'abc';
- };
- alert(obj=='abc');//这时就返回true了
- alert(obj==123);//false
- obj.valueOf=function () {return 123};
- alert(obj==123);//true!!!
- obj.valueOf=undefined;//先将这个方法清空掉,以免受上面的代码影响
- alert(obj==true);//false
- obj.valueOf=function () {
- return 1;//只要返回一个能转换成布尔值的标量就行了,1或true都行,都表示true
- };
- alert(obj==true);//true!!!!
事实上还可以用下面的代码进行验证,将一个复合对象与标量进行比较时,总会先调用对象的valueOf,
valueOf方法返回不是一个标量的话还会接着调用toString方法
- var obj={
- toString:function () {
- alert('valueOf方法没有返回标量,我会被调用');
- },
- valueOf:function () {
- alert('我先被调用,Object的valueOf方法默认实现是返回对象自身');
- }
- };
- 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都转换成数字再进行比较
也就是说
- var a="true";
- var b=true;
- alert(a==b);
- //结果等同于下面的代码
- alert(Number(a)===Number(b));
而如果a是Number,String,Boolean这三种类型中的一种,而b是一个复合对象时(Object,Array等)
则对b执行ToPrimitive操作(这步是JS解释器执行的)
即
- var a="abc";
- var b={};
- alert(a==b);
- //上面的一行代码在JS解析时将被解释成
- //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
转自:http://www.cnblogs.com/sking7/archive/2011/11/11/2245589.html