丧心病狂的js面试题

1
2
// 1. 下面代码输出什么?
console.log(++[[]][+[]] + [+[]]);

这算不上是一道好的面试题。虽然我认为这样的面试题不值得提倡,但是知识点还是要掌握。

拆解问题

把打印的表达式拆分成++[[]][+[]]+[+[]]三部分。注意这不是随意地拆分,是根据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()函数可以将值转换为布尔类型。

需要注意的是,类型转换可能会导致意外的结果。在进行类型转换时,应该注意数据的原始类型,并确保转换结果符合预期


丧心病狂的js面试题
https://jacksiongt.github.io/2025/04/20/丧心病狂的js面试题/
作者
Jacksion
发布于
2025年4月20日
许可协议