全等运算符 ===
全等和不全等操作符遵循以下基本规则(IEA规则):
- 如果两个操作数有不同的类型,它们不是严格相等的
- 如果两个操作数都为 null,则它们是严格相等的
- 如果两个操作数都为 undefined,它们是严格相等的
- 如果一个或两个操作数都是 NaN,它们就不是严格相等的
- 如果两个操作数都为 true 或都为 false,它们是严格相等的
- 如果两个操作数都是 number 类型并且具有相同的值,则它们是严格相等的
- 如果两个操作数都是 string 类型并且具有相同的值,则它们是严格相等的
- 如果两个操作数都引用相同的对象或函数,则它们是严格相等的
- 在全等运算中,NaN 与其他任何值相比,包括它本身,结果都是 false,
以上所有其他情况下操作数都不是严格相等的。
对象转换为原始值的规则
对象到布尔值
对象到布尔值的转换非常简单:所有的对象(包括数字和函数)都转换为 true
。对于包装对象亦是如此:new Boolean(false)
是一个对象而不是原始值,它将转换为 true
。
对象到字符串
对象到字符串 和 对象到数字 的转换都是通过调用待转换对象的一个方法来完成的。一个麻烦的事实是,JS 对象有两个不同的方法来执行转换,接下来要讨论的一些特殊场景更加复杂。值得注意的是,这里提到的字符串和对象的转换规则只适用于原生对象(native object)。宿主对象(例如有Web浏览器定义的对象)根据各自的算法可以转换成字符串和数字。
所有的对象继承了两个转换方法。第一个是toString()
,它的作用是返回一个反映这个对象的字符串:
({x:1,y:2}).toString() //=>"[object object]"
数组的 toString()
方法是将每个数组元素转换为一个字符串,并在元素之间添加逗号后合并成结果字符串。
[1,2,3,4].toString(); // "1,2,3,4"
函数的 toString()
方法返回了这个函数的实现定义。实际上,这里的实现是通常是将用户定义的函数转换为 JS 源代码字符串。
(function(x){ f(x); }).toString() // => "function(x){ f(x); }"
日期 Date 的 toString() 方法返回了一个可读的日期和时间字符串。
RegExp 的 toString() 方法将RegExp对象转换为表示正则表达式直接量的字符串:
new Date(2008,8,8).toString(); // "Mon Sep 08 2008 00:00:00 GMT+0800 (中国标准时间)"
/\d/g.toString(); // "/\d/g"
== 相等运算符
相等运算符 “==” 如果两个操作数不是同一类型,那么相等运算符会尝试一些类型转换,然后进行比较。
相等运算符算法(EEA)
- 如果操作数具有相同的类型,请使用上面的 IEA 测试它们是否严格相等。 如果它们不严格相等,则它们不相等,否则相等。
- 如果左右两边数据类型不一样,先转换为相同的数据类型,然后再进行比较:
- null == undefined ;结果为 true
- NaN == NaN ;结果为 false
- 对象和字符串比较,是把对象toString() 转换为字符串后再进行比较
- 其它所有情况在进行比较时,都是转换为数字类型:
- 对象转数字:先转换为字符串,再转换为数字
- 字符串转数字:只要出现一个非数字字符,结果就是NaN
- 布尔转数字:true->1 false->0
- null和undefined在和其它数据类型进行 == 比较时,结果永远为 false