【面试题-JS】[‘1‘,‘2‘,‘3‘].map(parseInt) 输出什么?

本文探讨了JavaScript代码中使用`parseInt`与`Array.prototype.map`时可能遇到的问题。通过分析`map`方法的工作原理和`parseInt`的参数解析,揭示了当不提供基数时,`parseInt`如何处理传入的参数,导致结果数组出现`NaN`的情况。结论是当使用`map`结合`parseInt`时,如果不指定基数,数组`['1','2','3']`会被转化为`[1, NaN, NaN]`。

我们来看下面这段代码:

 let a = ['1', '2', '3'].map(parseInt);
 console.log(a);

这段代码比较简单,但是我却连续踩了好几个坑。

再看分析之前,列几个参考选项吧~

A. [1,2,3]
B. [1,NaN,NaN]
C. ['1','2','3']
D. [NaN,NaN,NaN]
E. 正确答案不在这里
F.B

下面将从这道题目唯二的两个因素map,parseInt开始剖析这道题目。

Array.prototype.map()

MDN:map() 方法创建一个新数组,其结果是该数组中的每个元素是调用一次提供的函数后的返回值。

我们先回顾该方法的基本作用与参数:针对每一个元素都调用的回调函数callback(value,index,array) 以及传入该回调函数的 this指针。

//准备原材料
function myThisObj(){
  this.name = "myobj";
}
let obj = new myThisObj();
let oldArr = [10,20,30,40,50];

//开始实验
let newArr1 = oldArr.map(function(value,index,array){
  console.log(value,index,array,this);
},obj);
console.log("----------------");
let newArr2 = oldArr.map(function(value,index,array){
  console.log(value,index,array,this);
}); 
console.log("----------------");

输出的结果如下:
在这里插入图片描述

知道了map方法的基本功能后,回顾面试题,我们可以知道,输出的结果必定是每一个原数组元素调用函数parseInt返回结果新组合而成的Array(3)。那么问题便接踵而来了…

  1. 原题中,并没有给parseInt回调函数显示传入参数,是否意味着调用了parseInt()?
  2. 假如不传参调用了parseInt(),那么返回什么?
  3. 假如传参调用了parseInt(),那么传的什么参数?返回什么?
let newArr3 = oldArr.map(function(){
  console.log(...arguments);
}); 

答案是会,不管我们定义的是什么,map的回调函数都会传入那几个参数(当前值,当前下标,数组)。
在这里插入图片描述
所以实际上调用的是三次parseInt:并且每一次都是传入(值,下标,数组),得到的新数组等同于下面:

for(let i=0;i<oldArr.length;i++){
	newArr[i] = parseInt(oldArr[i],i,oldArr);
}

剩下的问题即是分析parseInt的方法:

parseInt

MDN:parseInt(string, radix) 解析一个字符串并返回指定基数的十进制整数, radix 是2-36之间的整数,表示被解析字符串的基数。

由于函数定义中只传入了两个参数,所以我们实际传入的第三个参数Array作废。我们考虑本题最终数组的三个值:

//第一个参数是值,第二个是下标
parseInt('1',0);
parseInt('2',1);
parseInt('3',2);

MDN文档中没有提及的是,如果传入的radix为0,1,那么结果如何?

  • 如果radix传入的是0或者空,那么parseInt默认按照十进制处理。(这里的1转成十进制的1)
  • 如果radix传入的是1,由于没有1进制,所以会返回NaN。 (不存在一进制== NaN)
  • 如果解析的字符串中无法解析成对应进制的number,同样会返回NaN。(这里的3无法转成二进制==NaN)

故答案为 B [1,NaN,NaN]

不传参的情况也顺带一提:

console.log(parseInt())//NaN 
### 3.1 JavaScript 相关面试题 #### 3.1.1 什么是闭包?请举例说明 闭包是指有权访问另一个函数作用域中的变量的函数。形成闭包的条件包括:存在一个内层函数,该内层函数引用了外层函数的变量,并且外层函数将内层函数作为返回值或者传递给其他地方进行调用[^4]。 **示例代码**: ```javascript function outerFunction() { var outerVariable = &#39;I am outside!&#39;; function innerFunction() { console.log(outerVariable); } return innerFunction; } var myClosure = outerFunction(); myClosure(); // 输出 "I am outside!" ``` #### 3.1.2 `map` 方法中使用 `parseInt` 会产生什么结果? `map` 的回调函数接受三个参数,分别是当前索引元素、索引、原数组。当使用 `parseInt` 作为 `map` 的回调函数时,由于 `parseInt` 接受两个参数(字符串和基数),而在 `map` 中传递了三个参数,导致第二个参数被误解为基数。 **示例代码**: ```javascript [&#39;1&#39;,&#39;2&#39;,&#39;3&#39;].map(parseInt); // 结果为 [1, NaN, NaN] ``` ### 3.2 CSS 相关面试题 #### 3.2.1 如何实现一个响应式布局? 响应式布局可以通过媒体查询(Media Queries)来实现。媒体查询允许根据设备特性(如屏幕宽度、高度等)应用不同的样式规则。 **示例代码**: ```css @media (max-width: 600px) { .container { flex-direction: column; } } ``` ### 3.3 ES6 相关面试题 #### 3.3.1 解释 `let` 和 `const` 的区别 `let` 允许声明一个变量,并且该变量可以在后续重新赋值;而 `const` 声明的变量不能重新赋值,但是如果是对象或数组,则其内部的属性或元素是可以修改的。 **示例代码**: ```javascript let a = 10; a = 20; // 合法 const b = 10; b = 20; // 报错 const obj = { key: &#39;value&#39; }; obj.key = &#39;new value&#39;; // 合法 ``` ### 3.4 Vue2 相关面试题 #### 3.4.1 Vue2 中如何实现响应式数据? 在 Vue.js 2.x 中,对于一个深层属性嵌套的对象,要劫持它内部深层次的变化,就需要递归遍历这个对象,执行 `Object.defineProperty` 把每一层对象数据都变成响应式的,这无疑会有很大的性能消耗[^1]。 ### 3.5 Vue3 相关面试题 #### 3.5.1 Vue3 中如何优化响应式系统的性能? 在 Vue.js 3.0 中,使用 Proxy API 并不能监听到对象内部深层次的属性变化,因此它的处理方式是在 getter 中去递归响应式,这样的好处是真正访问到的内部属性才会变成响应式,简单的可以说是按需实现响应式,减少性能消耗[^1]。 #### 3.5.2 Vue3 与 React 的主要区别是什么? Vue.js 在模板中提供了指令、过滤器等,可以非常方便、快捷地操作 Virtual DOM;而 React 采用的 Virtual DOM 会对渲染出来的结果做脏检查。两者虽然都推崇组件化开发,但 Vue.js 更加注重模板的便捷性和指令的灵活性[^2]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

如果皮卡会coding

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值