大厂就是吊,这面试题把我整懵了
大厂就是吊,这面试题把我整懵了
题目如下:
['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