开门见题
说出以下几个表达式的结果
var obj1 = { name: '张三'}
var obj2 = obj1
var obj3 = { name: '张三'}
null == undefined
123 == '123'
false == 0
NaN == false
obj1 == obj2
obj1 == obj3
补充知识
要想回答上述问题,必须理解js在执行==
时候的一些数据转换规则和成文的规定。ECMA-262对==
的约定如下:
x==y
-
如果x和y的类型相同,
- 如果x是undefined,return true
- 如果x是null,return true
-
如果x是Number
- x是NaN,return false
- y是NaN,return false
- x,y数值相同,return true
- x是+0,y是-0,return true
- x是-0,y是+0,return true
- 如果x是String,y必须和x长度内容都相同才return true,否则return false
- 如果x是Boolean,x,y相同return true,否则return false
- 如果x,y引用同一个对象,return true,否则return false
- x是null,y是undefined,return true
- x是undefined,y是null,return true
- x是Number,y是String,return x == ToNumber(y)
- x是String,y是Number,return ToNumber(x) == y
- x是Boolean,return ToNumber(x) == y
- y是Boolean,return x == ToNumber(y)
- x是String或Number,y是Object,return x == ToPrimitive(y)
- x是Object,y是String或Number,return ToPrimitive(x) == y
- return false
你可能注意到了这样两个函数
ToNumber()
参数类型 | 结果 |
---|---|
Undefined | NaN |
Null | +0 |
Boolean | true为1,false为+0 |
Number | 参数本身 |
String | 简单理解,能转换成数字的就会转换成数字,比如数字字符串,十六进制的数字等,转换失败则返回NaN(详见ECMA-262-9.3.1,内容较多,不展开叙述) |
Object | 两步转换操作:1. ToPrimitive(input argument, hint Number) 2. ToNumber() |
ToPrimitive()
参数类型 | 结果 |
---|---|
Undefined | 输入值 |
Null | 输入值 |
Boolean | 输入值 |
Number | 输入值 |
String | 输入值 |
Object | 调用DefaultValue方法 |
好吧,又多了一个DefaultValue方法
ToPrimitive()
细心的你发现上面ToNumber对于Object的转换里有这么一句ToPrimitive(input argument, hint Number)
,就是说调用ToPrimitive的时候,除了传入要转化的值,还传了一个hint参数,这个参数可以为Number,也可以为String。那么什么时候传入这两个参数,同时又有啥区别?
- 如果参数是
hint Number
:
- 先执行
valueOf
,如果返回值是原始值,则返回原始值 - 否则执行
toString
,如果返回值是原始值,则返回原始值 - 报错
- 如果参数是
hint String
:
- 先执行
toString
,如果返回值是原始值,则返回原始值 - 否则执行
valueOf
,如果返回值是原始值,则返回原始值 - 报错
如果input argument是内置的Date类型,则参数是hint String
,否则默认hint Number
。
回到题目
说了这么多,我们回到上面的题目,一一解答:
-
null == undefined
。根据上面第二条,写的明明白白,结果是true。 -
123 == '123'
。根据上面第四条return 123 == ToNumber('123')
,而ToNumber('123')
的结果为123,所以return 123 == 123
,根据1-3-3,返回true。 -
false == 0
。根据上面第六条,return ToNumber(false) == 0
,而ToNumber(false)
的值为+0,所以+0 == 0
,根据1-3-3,返回true。 -
NaN == false
。看到很多别的同学说这里是做了各种类型转换,其实我认为这里是由于没有匹配到任何规则,所以根据第十条返回false,也就是说并没有做什么类型转换。 -
obj1 == obj2
。根据1-6,由于obj1和obj2指向同一个引用,所以返回true。 -
obj1 == obj3
。根据1-6,由于obj1和obj2指向不同引用,所以返回false。
关于===
把上面题目中的==
换成===
,试问结果会发生怎样的变化?这里我就不说了,推理方式同上,根据如下规则,答案请各位看官自行补充。
x===y
- 如果x,y类型不同,return false
- 如果x是undefined,return true
- 如果x是null,return true
-
如果x是Number
- 如果x是NaN,return false
- 如果y是NaN,return false
- x,y数值相同,return true
- x是+0,y是-0,return true
- x是-0,y是+0,return true
- return false
- 如果x是String,y必须和x长度内容都相同才return true,否则return false
- 如果x,y引用同一个对象,return true,否则return false
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。