大厂就是吊,这面试题把我整懵了

234 阅读3分钟

大厂就是吊,这面试题把我整懵了

欢迎关注我的公众号《人生代码》

每天首发大厂面试题

题目如下:

['1', '2', '3'].map(parseInt)

然后让你说出返回值,以及为什么?

不得不说,大厂就是吊啊,是大厂真会造火箭,还是我们的基础不太好,明显是第二种嘛?一般人都会回答 ['1', '2', '3']

大佬们是不会回答 ['1', '2', '3'],而是回答 [1, NaN, NaN]

这就把我给整懵逼了,就这还能难得到我,诶,还真把我难倒了。

接下来我们就来好好解析一下为什么?

解析之前,我们得想想面试官到底想问什么?

我猜想有以下几个可能

  • map 方法
  • parseInt 方法

map 方法解析

['1', '2', '3'].map(function(item){
  console.log(item)
})

你以为他会只打印 1,2,3。其实不是,来看看浏览器控制台是怎么打印的:

1
2
3
(3)[undefined, undefined, undefined]

神了,还打印出四个值来,其实最后一个是返回值,就是因为function(item){} 没有真正的返回值,默认返回undefined

所以 map 之后返回一个三个 undefined 元素的数组

[undefined, undefined, undefined]

其实上面我们可以这样写,就更加清楚了

var a = ['1', '2', '3'].map((item) => console.log(item))
console.log(a)

其实打印出来就是:

[undefined, undefined, undefined]

继续深入研究:

['1', '2', '3'].map(function(item, index){
  // item: 数组元素
  // index: 数组元素的下标
  console.log(item, index)
})

会打印出:

item, index
1      0
2      1
3      2

继续深入研究:

['1', '2', '3'].map(function(item, index, array){
  console.log("item", item)
  console.log("index", index)
  console.log("array", array)
})

会打印出:

item 1
index 0
array (3) ["1", "2", "3"]
item 2
index 1
array (3) ["1", "2", "3"]
item 3
index 2
array (3) ["1", "2", "3"]

这里有个经常面试的考点就是考 map 与 forEach 的核心区别:

1. map 会重新返回数组
2. forEach 不会重新返回数组

ok

parseInt

记住核心的一点就是其实 parseInt(string, radix) 解析一个字符串并返回指定基数的十进制整数, radix 是2-36之间的整数,表示被解析字符串的基数。

parseInt 其实是有两个参数的,只是如果我们平时不注意的话,会以为只有一个参数,所以回答 ['1', '2', '3'] 可能就以为只有一个参数,而且会认为默认就是 10 进制的。

实际上面那道题目可以转化为:

['1', '2', '3'].map(parseInt(item, index))

是不是这样的呢?是的,就是这样的,他会把数组元素当做 parseInt 第一个参数,将数组元素的下标当做 parseInt 第二个参数

那么为什么是 [1, NaNa, NaN] 呢?

其实就是执行了三遍:

parseInt("1", 0) // 0
parseInt('2', 1) // NaN
parseInt('3', 2) // NaN

第一个元素是 1,是问啥。

如果 radix 是 undefined、0或未指定的,JavaScript会假定以下情况:

  • 如果输入的 string以 "0x"或 "0x"(一个0,后面是小写或大写的X)开头,那么radix被假定为16,字符串的其余部分被当做十六进制数去解析。

  • 如果输入的 string以 "0"(0)开头, radix被假定为8(八进制)或10(十进制)。具体选择哪一个radix取决于实现。ECMAScript 5 澄清了应该使用 10 (十进制),但不是所有的浏览器都支持。因此,在使用 parseInt 时,一定要指定一个 radix。

  • 如果输入的 string 以任何其他值开头, radix 是 10 (十进制)。

  • 如果第一个字符不能转换为数字,parseInt会返回 NaN。

那么第二个元素是 NaN,很纳闷。

你想想看:

radix 可选

从 2 到 36,表示字符串的基数。例如指定 16 表示被解析值是十六进制数。请注意,10不是默认值!

没有 1进制转换,所以是 NaN。

第三个元素是 NaN 又是为啥呢?

parseInt('3', 2) // NaN

因为 2 进制转换,只有 0 和 1,2进制没法表示 3

所以打印出来就是 NaN