2019-01-23
jsfuck
类型转换问题
最近比较频繁的碰见 JavaScript 类型转换的问题:
00const res1 = [] + {}; 
01// => '[object Object]' 
02
03const res2 = {} + [];
04// => '[object Object]' 
05
06const res3 = eval('{} + []');
07// => 0
08
09console.log(res1);
10console.log(res2);
11console.log(res3);

# res1

  1. 计算 [] + {} 的时候,先要转换 [] 为原始类型,那该怎么转换呢,看加数的类型。
  2. 加数是对象,调用它的 valueOf, 结果还是对象,最后调用 toString() 得 ‘[object Object]’
  3. 之后计算 [] + ‘[object Object]’
  4. [] 调用 valueOf 得到它自己,然后调用 toString 得到空字符串,所以最终答案是 ‘[object Object]’

# res2

没什么特别的,跟上面一样。

# res3

{} 被解释为代码快,源代码等价于:
00console.log(
01    // 打印一下这个表达式的最终结果
02    +[]
03);
其实就是 +[] 答案是 0,为啥呢,因为 [].valueOf 是它自己,然后调用 toString 是空字符串,最后得到 (+""),等价于 Number("") 得到 0

# valueOf、toString 优先级

valueOf toString 的优先级可以通过几个例子说明:
00console.log(
01    // string + object
02    ('20' + {
03        valueOf: () => 2, 
04		toString: () => '20'
05    })
06);
07// => '202'
08
09console.log(
10    // object + string
11    ({
12        valueOf: () => 2, 
13		toString: () => '20'
14    } + '20')
15);
16// => '220'
17
18console.log(
19    // object + object
20    ({
21        valueOf: () => 1, 
22		toString: () => '10'
23    } + {
24        valueOf: () => 2, 
25		toString: () => '20'
26    })
27);
28// => 3
说明无论什么情况下,优先调用 valueOf,其次才是 toString,其调用顺序是操作数无关的,也就是说被加数或者加数是啥类型它不会管。

# jsfuck

http://www.jsfuck.com/




回到顶部