25

开门见题

说出以下几个表达式的结果

var obj1 = { name: '张三'}
var obj2 = obj1
var obj3 = { name: '张三'}

null == undefined
123 == '123'
false == 0
NaN == false
obj1 == obj2
obj1 == obj3

补充知识

要想回答上述问题,必须理解js在执行==时候的一些数据转换规则和成文的规定。ECMA-262对==的约定如下:
2762?ynotemdtimestamp=1532482432857

x==y

  1. 如果x和y的类型相同,

    1. 如果x是undefined,return true
    2. 如果x是null,return true
    3. 如果x是Number

      1. x是NaN,return false
      2. y是NaN,return false
      3. x,y数值相同,return true
      4. x是+0,y是-0,return true
      5. x是-0,y是+0,return true
    4. 如果x是String,y必须和x长度内容都相同才return true,否则return false
    5. 如果x是Boolean,x,y相同return true,否则return false
    6. 如果x,y引用同一个对象,return true,否则return false
  2. x是null,y是undefined,return true
  3. x是undefined,y是null,return true
  4. x是Number,y是String,return x == ToNumber(y)
  5. x是String,y是Number,return ToNumber(x) == y
  6. x是Boolean,return ToNumber(x) == y
  7. y是Boolean,return x == ToNumber(y)
  8. x是String或Number,y是Object,return x == ToPrimitive(y)
  9. x是Object,y是String或Number,return ToPrimitive(x) == y
  10. 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:
  1. 先执行valueOf,如果返回值是原始值,则返回原始值
  2. 否则执行toString,如果返回值是原始值,则返回原始值
  3. 报错
  • 如果参数是hint String:
  1. 先执行toString,如果返回值是原始值,则返回原始值
  2. 否则执行valueOf,如果返回值是原始值,则返回原始值
  3. 报错

如果input argument是内置的Date类型,则参数是hint String,否则默认hint Number

回到题目

说了这么多,我们回到上面的题目,一一解答:

  1. null == undefined。根据上面第二条,写的明明白白,结果是true。
  2. 123 == '123'。根据上面第四条return 123 == ToNumber('123'),而ToNumber('123')的结果为123,所以return 123 == 123,根据1-3-3,返回true。
  3. false == 0。根据上面第六条,return ToNumber(false) == 0,而ToNumber(false)的值为+0,所以+0 == 0,根据1-3-3,返回true。
  4. NaN == false。看到很多别的同学说这里是做了各种类型转换,其实我认为这里是由于没有匹配到任何规则,所以根据第十条返回false,也就是说并没有做什么类型转换。
  5. obj1 == obj2。根据1-6,由于obj1和obj2指向同一个引用,所以返回true。
  6. obj1 == obj3。根据1-6,由于obj1和obj2指向不同引用,所以返回false。

关于===

把上面题目中的==换成===,试问结果会发生怎样的变化?这里我就不说了,推理方式同上,根据如下规则,答案请各位看官自行补充。
2934?ynotemdtimestamp=1532482432857

x===y

  1. 如果x,y类型不同,return false
  2. 如果x是undefined,return true
  3. 如果x是null,return true
  4. 如果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
  5. 如果x是String,y必须和x长度内容都相同才return true,否则return false
  6. 如果x,y引用同一个对象,return true,否则return false

志如
333 声望5 粉丝