序言
map()方法你懂了?OK!parseInt()呢?也懂了?OK!
js
console.log([1,2,3].map(parseInt))
面试官:来聊聊这个式子的打印结果,并谈谈你的理解?
纳尼?乍一看这是什么奇形怪状的组合?不要抓耳挠腮,通过这篇文章,就算是map()和parseInt()的梦幻联动
,也不能对你奈何,Let's GO!!!
Array.prototype.map()
JavaScript 中的数组是一种强大而灵活的数据结构,为了更方便地对数组进行操作,数组提供了一系列的方法。其中之一就是 Array.prototype.map()
,这个方法可以让我们轻松地对数组中的每个元素进行操作,创建一个新的数组,而不改变原始数组的内容。
基本语法
首先,让我们看一下 Array.prototype.map()
的基本语法:
javascript
arr.map(callback(currentValue, index, array), thisArg)
-
callback
: 为数组中每个元素执行的函数。这个函数可以接收三个参数:currentValue
: 数组中当前正在处理的元素。index
(可选): 正在处理的元素在数组中的索引。array
(可选): 调用了map()
的数组本身。
-
thisArg
(可选): 执行callback
函数时,用作this
的值(参见MDN文档 迭代方法 )
返回值
map()
方法会返回一个新数组,其中的元素是对原始数组中的每个元素应用回调函数的结果。
示例
让我们通过一些简单的例子来理解 map()
的使用:
示例1
javascript
// 将数组中的每个元素乘以 2
const numbers = [1, 2, 3, 4];
const doubled = numbers.map((num) => num * 2);
console.log(doubled); // 输出: [2, 4, 6, 8]
在这个例子中,map
方法遍历了数组 numbers
中的每个元素,并将其传递给箭头函数,然后返回一个新数组,其中的每个元素都是原始数组元素乘以 2 的结果。
示例2
js
const numbers = [1, 4, 9];
const roots = numbers.map((num) => Math.sqrt(num));
// roots 现在是 [1, 2, 3]
// numbers 依旧是 [1, 4, 9]
上面的代码创建了一个新数组,值为原数组中对应数字的平方根。
示例3
js
const kvArray = [
{ key: 1, value: 10 },
{ key: 2, value: 20 },
{ key: 3, value: 30 },
];
const reformattedArray = kvArray.map(({ key, value }) => ({ [key]: value }));
console.log(reformattedArray); // [{ 1: 10 }, { 2: 20 }, { 3: 30 }]
console.log(kvArray);
// [
// { key: 1, value: 10 },
// { key: 2, value: 20 },
// { key: 3, value: 30 }
// ]
上面代码使用一个包含对象的数组来重新创建一个格式化后的数组。
示例4
js
const numbers = [1, 4, 9];
const doubles = numbers.map((num) => num * 2);
console.log(doubles); // [2, 8, 18]
console.log(numbers); // [1, 4, 9]
上面的代码表示了当函数需要一个参数时 map
的工作方式。当 map
循环遍历原始数组时,这个参数会自动被分配成数组中对应的每个元素。
注意事项
map
不会修改原始数组,而是返回一个新数组
,这有助于保持数据的不可变性。- 如果回调函数不改变元素的值,
map
将返回与原始数组相同的新数组。 - 可以使用
thisArg
参数来设置回调函数中的this
的值。
使用 thisArg
thisArg
参数的使用可以在回调函数中设置 this
的值,让我们通过一个例子来说明:
javascript
const obj = { multiplier: 2 };
const numbers = [1, 2, 3, 4];
const doubledWithThisArg = numbers.map(function(num) {
return num * this.multiplier;
}, obj);
console.log(doubledWithThisArg); // 输出: [2, 4, 6, 8]
在这个例子中,thisArg
被设置为 { multiplier: 2 }
,回调函数中的 this.multiplier
就可以访问这个值。
总体来说,
Array.prototype.map()
是一个强大而灵活的数组方法,它为我们提供了一种简单的方式来处理数组元素,创建新的数组,从而使我们的代码更加清晰和易读。无论是对数组中的每个元素执行相同的操作,还是根据特定的逻辑转换数组的内容,map
都是一个值得掌握的工具。
parseInt()
JavaScript其中的内置函数parseInt()
为我们提供了一种将字符串转换为整数的便捷方法。通过深入了解parseInt()
的用法和特性,我们能更好地理解其在处理数据时的行为。
基本语法
parseInt()
函数的基本语法如下:
javascript
parseInt(string, radix);
string
:要被解析的值。如果参数不是一个字符串,则将其转换为字符串 (使用 ToString()MDN详解
抽象操作)。字符串开头的空白符将会被忽略。radix
(可选):表示要解析的数字的基数。默认为10。从2
到36
的整数,表示进制的基数。例如指定16
表示被解析值是十六进制数。如果超出这个范围,将返回NaN
。假如指定0
或未指定,基数将会根据字符串的值进行推算。注意,推算的结果不会永远是默认值10
!
返回值
parseInt()
函数会返回解析后的整数。如果无法解析,则返回 NaN
(Not a Number):
radix
小于2
或大于36
,或- 第一个非空格字符不能转换为数字。
js
parseInt('123', 5) // 将'123'看作 5 进制数,返回十进制数 38 => 1*5^2 + 2*5^1 + 3*5^0 = 38
示例
让我们通过一个简单的例子来演示parseInt()
的使用:
javascript
const binaryString = "1010";
const decimalNumber = parseInt(binaryString, 2);
console.log(decimalNumber); // 输出: 10
在这个例子中,parseInt
将二进制字符串 "1010"
解析为十进制整数 10
。
注意事项
在使用parseInt()
时,需要注意以下几点:
- 无法解析时返回 NaN :如果字符串的第一个字符不能被转换为数字,
parseInt()
将返回NaN
。因此,在使用其结果之前,通常需要检查是否成功解析。 - 解析规则 :
parseInt()
会从字符串的开头开始解析,直到遇到不能被解析为数字的字符为止。它会忽略字符串中的空格。 - 基数参数 :
radix
参数表示要解析的数字的基数,可以是 2 到 36 之间的整数。如果省略或是 0,则默认为 10。通过设置基数,我们可以解析不同进制的数字字符串,如十六进制、八进制等。
使用基数参数
javascript
const hexString = "1a";
const decimalNumber = parseInt(hexString, 16);
console.log(decimalNumber); // 输出: 26
在这个例子中,parseInt
将十六进制字符串 "1a"
解析为十进制整数 26
。
总体来说,
parseInt()
是一个在处理字符串到整数转换时非常实用的工具。但需要注意,它并不适用于所有情况,特别是当涉及浮点数时。此外,在 ECMAScript 6 及之后的版本中,推荐使用Number.parseInt()
,而不是将其作为全局函数直接调用。深入理解这个函数的使用方式和特性,有助于我们更有效地处理字符串和数字之间的转换操作。
Array.map(parseInt)
map + parseInt 是面试中的经典题目,主要考察了我们对于map()方法和parseInt()方法的掌握以及结合使用,接下来哦我们来看一道题帮助理解这两种方法的结合使用。
javascript
console.log([1,2,3].map(parseInt));
这里,Array.prototype.map()
遍历数组 [1,2,3]
,对每个元素应用 parseInt
函数。但是,由于 parseInt
接受三个参数(字符串、基数、数组索引),而 map
只传递了两个参数(当前元素和当前索引),这种参数不对应就可能导致一些出人意料的结果。
详细解释一下:
javascript
console.log([1,2,3].map(parseInt));
-
parseInt(1, 0, [1,2,3])
:- 解析字符串 "1",基数为 0(自动判断基数),后面为无效参数。
- 结果为十进制数 1。
-
parseInt(2, 1, [1,2,3])
:- 解析字符串 "2",基数为 1(
无效
的基数,因为基数必须在 2 到 36 之间),后面为无效参数。 - 因为基数无效,结果为
NaN
。
- 解析字符串 "2",基数为 1(
-
parseInt(3, 2, [1,2,3])
:- 解析字符串 "3",基数为 2(解析为二进制数),后面为无效参数。
- 结果为
NaN
,因为3
并不是一个有效的2
进制数,parseInt
返回NaN
。
因此,最终的输出结果是 [1, NaN, NaN]
。
避免混淆的方法
为了避免这种混淆,可以使用箭头函数将 parseInt
的调用包装在一个函数内,确保只接受一个参数:
javascript
console.log([1,2,3].map(num => parseInt(num)));
这样就能得到预期的结果 [1, 2, 3]
,因为箭头函数只接受一个参数,与 parseInt
的预期用法一致。通过了解每个函数的用途和参数,我们可以更好地理解代码的行为,并避免意外的结果。
总结
通过这篇文章我们深刻地理解了Array.prototype.map()
和parseInt()
的语法及使用,然后通过一个经常会引起混淆的例子来深入剖析函数执行过程,加深巩固了对这两种语法的使用,只要我们对这两种语法的理解到位,尽管面试官给的例子再千奇百怪,我们也能直接拿下!
md
# map + parseInt 经典题目
- MDN文档
map callback 返回值是由callback每一项组成的一个新数组
callback 会接收到`item`(当前项) `index`当前项在数组中的下标(索引) `array`(数组本身) 三个参数
parseInt 就是当前的callback item,可选的参数 ?radix(进制基数)
默认 10 进制
0 无效 , 使用10
1进制 如果item为2, NaN
2进制 如果item为3, NaN