关于 JavaScript 隐式转换的一道题

关于 JavaScript 隐式转换的一道题

让我们先看一道面试题

1
2
3
当 a==1 && a==2 && a==3 为 true 时,a = ?
简要分析 a 多次 == 一个不同的值成立,由此可以推断 a 是一个引用类型的值
且比较时用到 == 而不是 === ,可以判断这道题考察的是 js 的隐式转换问题

其他值转换为字符串

  • 当值是原始类型时,直接转换为字符串类型
1
2
3
4
null => 'null'
undefined => 'undefined'
true => 'true'
1 => '1'
  • 当值是引用类型时,先转换为原始类型,再转换为字符串.String方法背后的转换规则与Number方法基本相同,只是互换了valueOf方法和toString方法的执行顺序。
1
2
3
String([1,2,3]) // 1,2,3 因为[1,2,3].toString() 是'1,2,3',再调用 valueOf 是'1,2,3'
String([]) // ''
{a:1} // [object object]

其他值转换为数字类型

  • 当值是原始类型的转换规则
1
2
3
4
5
6
// 数字类型转数字类型
Number(123) // 123
// 字符串转数字类型
Number('123a') // NaN Number 比 parseInt 严格,当有字符串无法转换时返回 NaN,而 parseInt 返回已经转换的值, 空字符串转成0
// 布尔值:true 转成 1,false 转成 0
// undefined:转成 NaN ,null 转成0
  • 当值是引用类型时的转换规则
1
2
// 先调用 valueOf(),如果不是原始类型的值再调用 toString,然后Number
Number({x: 1}) // NaN

其他值转换为布尔值

只有 null,undefined,0,空字符串,NaN 转换为 false,其他所有值都转为 true

引用类型转换为原始类型

先调用 valueOf(),如果未返回原始类型的值,再调用 toString()

== 比较时的隐式转换规则

用一句话概括就是原始类型转数字,引用类型转原始类型

1
2
3
4
true == 2 (布尔值先转换为数字类型再参与比较)
11 == ‘11’ (字符串转换为数字类型再参与比较)
{a:1} == ‘a:1’ (复杂类型转换为原始类型再参与比较)
null,undefined 互相==,与自身==,但与其他所有值都不==

解析面试题

我们可以推测出 a 是引用类型,引用类型与原始类型比较时会先转换成原始类型参与比较,所以 a 每次参与比较都会先后调用自身的 valueOf()和 toString()方法,所以在最后调用 toSring 时让自身递增,就可以让条件成立.所以 a 的值就是.

1
2
3
4
5
6
7
a = {
i:1,
toString: function(){
return a.i++
}
}
a == 1 && a==2 & a==3 // true