丧心病狂的js面试题
1 | |
这算不上是一道好的面试题。虽然我认为这样的面试题不值得提倡,但是知识点还是要掌握。
拆解问题
把打印的表达式拆分成++[[]][+[]] 、 +、 [+[]]三部分。注意这不是随意地拆分,是根据JavaScript表达式及运算符号优先级进行拆分的。同样地,将拆分后得到地表达式按照同样的方法逐步拆分运算。
step 1
先来看第一部分++[[]][+[]] 继续拆分 ++ [[]] [+[]]
[[]],这是一个数组,数组只有一个元素,这个元素是一个空数组[]。- 然后来看
[+[]],这也是一个数组,数组只有一个元素。运算后得到[0] - 组合
[[]][+[]]得到[[]][0],意思是取得数组[[]]的第0个元素,运算结果为[] ++[]运算结果就是数字类型的值1
step 2
再来看第三部分[+[]] 运算过程在step 1已经分析过了,运算后结果为[0]。
step 3
然后把+前后的运算结果组合起来1 + [0],结果为字符传类型的"10"。
计算过程
前面简单说明了表达式拆分及计算结果,现在来详细解释一下JavaScript中运算符的类型转换规则及取值过程。
计算 [+[]]
- 来看
[+[]]中+[]的计算。+[]意思是把数据(这里是一个空数组)转换成数字 - 这个转换过程就是JavaScript尝试取得原始值。
[]首先调用[].valueOf(),还是得到[] - 由于上一步未取得原始值,继续调用
[].toString(),得到""。空字符串是原始值 - 继续调用
+""。在表达式+''中,''是一个空字符串。当+运算符应用于一个空字符串时,它会将空字符串转换为数字。根据JavaScript的类型转换规则,一个空字符串在转换为数字时会被解释为0。因此,+''的结果是数字类型的值0。 [+[]]的运算结果就是[0]
计算 ++[]
这里提一下,++自增运算符只能应用于变量或对象的属性,而不能直接应用于字面量或表达式。
++[]在自增之前首先要取得[]的原始值[]的原始值运算过程前面已经介绍过了,[]的原始值运算结果是空字符串""- 继续计算
+"",这个跟前面也是一样的。运算结果为数字类型的0 ++[]就是计算++0,0自增1后得到数字类型1。
计算 1 + [0]
- 这个表达是首先会尝试取得
[0]的原始值 - 首先调用
[0].valueOf(),运算结果还是数组[0] - 继续调用
[0].toString(),得到 字符串类型"0" - 最后计算
1 + "0"得到字符串"10"
总结
这道题考察了JavaScript语言的运算符优先级规则、类型转换规则、各种数据类型数据转换成原始值的方法(拆箱)。
参考
- JavaScript运算符优先级
- 常见的类型转换规则:
字符串转换:当一个值与字符串进行操作时(例如使用+运算符连接字符串),JavaScript会将该值转换为字符串类型。这种转换称为字符串转换。
数字转换:当一个值与数字进行操作时(例如使用+运算符进行加法运算),JavaScript会将该值转换为数字类型。这种转换称为数字转换。
布尔转换:在需要布尔值的上下文中,JavaScript会将值转换为布尔类型。以下值会被转换为false:false、null、undefined、0、NaN和空字符串 ‘’。其他所有值都会被转换为true。
对象转换:当一个非原始值(例如对象、数组)与字符串或数字进行操作时,JavaScript会尝试将其转换为相应的原始类型。这种转换称为对象转换。对象转换通常通过调用对象的toString()或valueOf()方法来完成。
显式类型转换:JavaScript提供了一些内置函数来进行显式的类型转换。例如,Number()函数可以将值转换为数字类型,String()函数可以将值转换为字符串类型,Boolean()函数可以将值转换为布尔类型。
需要注意的是,类型转换可能会导致意外的结果。在进行类型转换时,应该注意数据的原始类型,并确保转换结果符合预期