![['1', '7', '11'].map(parseInt)](https://p1-jj.byteimg.com/tos-cn-i-t2oaga2asx/gold-user-assets/2020/1/12/16f9924cc91857eb~tplv-t2oaga2asx-jj-mark:3024:0:0:0:q75.png)
相信很多人会对上面的执行结果感到疑惑,不要着急,相信看完这篇文章后,你会对javascript的运行机制又有更进一步的理解。
首先我们需要澄清以下几个概念:
Boolean 对象
if ("hello world") {
// will this run?
console.log("Condition is truthy");
} else {
// or this?
console.log("Condition is falsy");
}
上述代码会输出Condition is truthy。
Boolean(布尔)对象用于将非布尔值转换为布尔值( "true" 或者 "false"),
当Boolean对象的值为:
- 0
- -0
- null
- ""
- false
- undefined
- NaN
那么对象的值为 false。否则,其值为 true(包括:“false”, "0", {} 和 [])!
arguments对象
在Javascript函数参数个数是不固定的, 即使他们不等于声明函数参数的数量。缺少的参数被当做undefined的和多余的参数会被忽略
function foo(x, y) {
console.log(x);
console.log(y);
}
foo(1, 2); // logs 1, 2
foo(1); // logs 1, undefined
foo(1, 2, 3); // logs 1, 2
Array map()的用法
map() 方法返回一个新数组,数组中的元素为原始数组元素调用函数处理后的值。
function multiplyBy3(x) {
return x * 3;
}
const result = [1, 2, 3, 4, 5].map(multiplyBy3);
console.log(result); // logs [3, 6, 9, 12, 15];
传入console.log用于输出数组中的每个元素:
[1, 2, 3, 4, 5].map(console.log);
![[1, 2, 3, 4, 5].map(console.log)](https://p1-jj.byteimg.com/tos-cn-i-t2oaga2asx/gold-user-assets/2020/1/12/16f992538a761b19~tplv-t2oaga2asx-jj-mark:3024:0:0:0:q75.png)
神奇的事情发生了,结果并不是我们预想的,输出的是每个元素,元素的下标和整个数组对象。
当一个函数被传入map中,这个函数被传入三个参数: currentValue, currentIndex 和 array:
[1, 2, 3, 4, 5].map(console.log);
// 等价于
[1, 2, 3, 4, 5].map(
(val, index, array) => console.log(val, index, array)
);
// 不等价于
[1, 2, 3, 4, 5].map(
val => console.log(val)
);
言归正传
现在是时候回到文章开头提到的问题了。
为什么['1', '7', '11'].map(parseInt)返回值是[1, NaN, 3]呢?
parseInt用法
parseInt() 函数可解析一个字符串,并返回一个整数。
语法:
parseInt(string, radix)
| 参数 | 描述 |
|---|---|
| string | 必需。要被解析的字符串。 |
| radix | 可选。表示要解析的数字的基数。该值介于 2 ~ 36 之间。 |
如果radix参数省略或其值为 0,则数字将以 10 为基础来解析。如果它以 “0x” 或 “0X” 开头,将以 16 为基数。如果该参数小于 2 或者大于 36,则 parseInt() 将返回 NaN。
我们看几个例子:
parseInt('11'); => 11
parseInt('11', 2); => 3
parseInt('11', 16); => 17
parseInt('11', undefined); => 11 (radix is false)
parseInt('11', 0); => 11 (radix is false)
基于上述的理解,我们对['1', '7', '11'].map(parseInt)的推演过程:
['1', '7', '11'].map(parseInt); => [1, NaN, 3]
// 第一次遍历: val = '1', index = 0, array = ['1', '7', '11']
parseInt('1', 0, ['1', '7', '11']); => 1
// 第二次遍历: val = '7', index = 1, array = ['1', '7', '11']
parseInt('7', 1, ['1', '7', '11']); => NaN
// 第三次遍历: val = '11', index = 2, array = ['1', '7', '11']
parseInt('11', 2, ['1', '7', '11']); => 3
由于parseInt只接收两个参数,自动会忽略第三个参数。
parseInt('1', 0): 由于radix参数传入了0,那么默认以10为基础计算,所以得到 1。
parseInt('7', 1): 由于radix参数传入了1,返回 NaN。
parseInt('11', 2): 由于radix参数传入了2,返回 3。
思考
我们已经知道['1', '7', '11'].map(parseInt)输出的结果[1, Nan, 3], 如果想得到[1, 7, 11]这样的结果,应该如何处理呢?
给你们思考3分钟吧 😝😝😝
['1', '7', '11'].map(numStr => parseInt(numStr));
你想到了吗?