Javascript的等号判断似乎有点难以让人理解,不少同学都有点晕。一起来梳理下:
Javascript的相等判断有两种: 1)== 2) ===
===(全等)
我们倒过来说,先看看三个等号。看过《Javascript权威指南》的同学印象查能比较深,用我自己的理解就是:如果左右两边都是引用类型时,如果两边都指向同一个元素则返回true,否则返回false。如果其中一个是引用类型另一个不是那肯定返回false了。如果左右两边都是简单类型而且值相同时返回true。
特别的:undefined 全等 undefined
这个看起来比较容易懂了,看看下面的例子:
alert( 0 === 0 ); // true
var obj = {} ;
var obj1 = obj ; //obj1复制了obj的引用
alert( obj1 === obj ) // true
alert( {} === {} ) //任何两个对象都不相等也不全等
== (相等)
相等的规则有点有复杂:
- 如果其中一个操作数的类型为 Boolean ,那么,首先将它转换为数字类型,false 转换为 0, true 将转换为 1。
- 如果其中一个操作数的类型是字符串,另外一个为数字类型,那么,将字符串转换为数字进行比较。
- 如果其中一个操作数的类型是字符串,另外一个为 object 类型,那么,将调用对象的 toString 方法之后,比较字符串。
- 如果其中一个操作数的类型是数字类型,另外一个为 object 类型,那么,将对象转换为数值后进行数字比较。
特别的:
- null 和 undefined 是相等的。
- null 和 undefined 不会转换为任何其他类型
- 如果任何一个操作的结果为 NaN,那么相等比较返回 false,不相等比较返回 true。注意,即使两个操作数都为 NaN,返回结果一样是 false,也就是说,NaN 不等于 NaN。
- 如果两个操作数都是对象,那么比较它们引用的值,如果引用同一个对象,那么,返回真,否则,返回假。
虽然详细都写了出来,但具体用起来还是有点小难度。看看下面几种情况:
1)在函数内判断变量有没有被赋值。
一般一个形参或通过var定义的变量在未赋值情况下值为undefined,此时要判断就得写成:
function test( p ){
if( p === undefined ){
alert("P值未传")
}
}
当然,如果调用者直接写了 test(undefined) 的话我就没办法了。
2) 用 !-[1,] 判断为IE8及以下浏览器
首先这里绝不是告诉大家有这个办法检测浏览器,但我不确定这是不是一个靠谱的办法。这种hack办法不知道MS啥时候会一个补丁给干掉,毕竟人家没直接说这是人家的特性。
这里写 if( !-[1,] ) 其实跟 if( !-[1,] == false )是一个概念。按相等判定规则的第一条,左右都换成数字类型。错就错在MS并没有完全按ECMA262中关于数组初始化定义的解释,见体看里:http://www.w3.org/html/ig/zh/wiki/ES5/%E8%A1%A8%E8%BE%BE%E5%BC%8F#.E6.95.B0.E7.BB.84.E5.88.9D.E5.A7.8B.E5.8C.96,按ECMA262所述 [1,] 应该直接返回 [1] ,但杯具的是IE8及以下解释成了 [1,undefined]。[1].toString()的结果是 "1" 而 [1,undefined].toString()的结果是 "1,"。然后再是-号,此时由于-号的参与需要将"1"或"1,"转成Number,所以表达式在IE8及以下就变成了:!( 0 - Number( "1,") ) ==》 !( 0 - NaN ) ==> !NaN ==> true 而其他浏览器解释成了:!( 0 - Number("1") ) ==> !( 0 - 1 ) => ! -1 ==> false 。
3)关于 ![] == []
![] == [] 表达式左边先运行得到 false ,这样就成了 false == [] 。同样按第一条规则两边都需要转成数字:Number( false ) == Number( [] )这样就得到了 0 == 0 结果成立。
原文见这里:http://www.xdarui.com/index.php/archives/131