Why [ '1', '7', '11']. Map (parseInt) return [1, NaN, 3]

Translation alentan

Original medium.com/dailyjs

Javascript is very strange. do not trust me? ParseInt map and attempt to use to convert an array of strings to integers. Start console (F12 on Chrome), paste the following, and then press Enter

['1', '7', '11'].map(parseInt);
复制代码

Is not a [1, 7, 11] so that we end up with an array of integers, but this [1, NaN, 3] Such an array length. To understand what happened in the end, we must first discuss some Javascript concepts. If you want a summary (TLDR), I added a quick summary at the end of this story.

True & false value

This is the Javascript in a simple if-else statement:

if (true) {
    // 永远都会运行
} else {
    // 永远不会运行
}
复制代码

In this case, if-else statement condition is true, and therefore always executed if-block statement block and ignore else-block block. This is a simple example, because true is a Boolean value. If we as a condition for non-Boolean value what will happen?

if ("hello world") {
    // 他会运行吗?
    console.log("Condition is truthy");
} else {
    // 还是运行这个?
    console.log("Condition is falsy");
}
复制代码

Try to run this code (F12 on Chrome) browser console. You should find a block of statements if-block run. This is because the string object "hello world" is true.

Each Javascript object when placed in the context is a Boolean true or false value. For example if-else statement, would Javascript objects into true or false. So what the object is true and what is false it? This is a simple rule:

Javascript, when the following values ​​are placed in return false boolean context

false, 0 ( "" empty string), null, undefined and NaN.

Hexadecimal (base)

0 1 2 3 4 5 6 7 8 9 10
复制代码

When we count from 0 to 9, each number (0-9) has a different sign. However, once we reach 10, we need two different symbols (1 and 0) to represent numbers. This is because the base of our decimal counting system (or hex) is 10.

Base is the smallest number that can only be represented by a plurality of symbols. Different systems have different base count, and therefore, like numerals may refer to a different digital counting system.

10进制    二进制    16进制
0         0         0
1         1         1
2         10        2
3         11        3
4         100       4
5         101       5
6         110       6
7         111       7
8         1000      8
9         1001      9
10        1010      A
11        1011      B
12        1100      C
13        1101      D
14        1110      E
15        1111      F
16        10000     10
17        10001     11
复制代码

For example, see the above table, we see the same numeral 11 may represent different numbers in different counting system. If the binary (radix) of 2, number 3 indicates. If the hexadecimal (base) 16, numeral 17 indicates.

You may have noticed that, in our example, when the input is 11, parseInt returns 3, which corresponds to a binary column in the table above.

Function Arguments

Javascript function can use any number of arguments, the number of function parameters even if they are not equal statement. Missing parameters are considered undefined, and the extra parameters are ignored (but will be stored in the parameter array-like objects in).

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
复制代码

map () function

We're almost there!

Map Array prototype is a method that returns a new array, the result is to pass each of the elements of the original array to a function. For example, the following code is multiplied by each element of the array 3

function multiplyBy3(x) {
    return x * 3;
}
const result = [1, 2, 3, 4, 5].map(multiplyBy3);
console.log(result);   // logs [3, 6, 9, 12, 15];
复制代码

Now, suppose I want to use map () (no return statement) records for each element. I should be able to map console.log passed as a parameter () ......

[1,2,3,4,5] .map(console.log);
复制代码

Some very strange things are happening. Console.log every call is recorded and a complete index of the array, rather than just record values.

[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)
);
复制代码

When passed to a function map (), for each iteration, three parameters passed to the function: currentValue, currentIndex, and the complete array. That's why each iteration recorded three entries.

We now have all the parts needed to solve the mystery.

Solve the mystery

ParseInt two arguments: string and radix (decimal). If the supplied radix (hexadecimal) is empty or false value, hexadecimal (base) The default setting is 10.

parseInt('11');                => 11
parseInt('11', 2);             => 3
parseInt('11', 16);            => 17
parseInt('11', undefined);     => 11 (radix(进制) 为假)
parseInt('11', 0);             => 11 (radix(进制) 为假)
复制代码

Now let's step by step run our example.

['1', '7', '11'].map(parseInt);       => [1, NaN, 3]
// 第一次迭代: val = '1', index = 0, array = ['1', '7', '11']
parseInt('1', 0, ['1', '7', '11']);   => 1
复制代码

Since 0 is false, and therefore hexadecimal (base) set to the default value of 10. the parseInt () accepts two parameters only, and therefore [ '1', '7', '11'] are ignored. String of '1' in the string (base) in a 10 hexadecimal numbers.

// 第二次迭代: val = '7', index = 1, array = ['1', '7', '11']
parseInt('7', 1, ['1', '7', '11']);   => NaN
复制代码

In a binary system (base) of the mark '7' does not exist. Like the first iteration, the last parameter is ignored. So, parseInt () returns NaN.

// 第三次迭代: val = '11', index = 2, array = ['1', '7', '11']
parseInt('11', 2, ['1', '7', '11']);   => 3
复制代码

In hexadecimal (radix) of 2 (binary) systems, the symbol '11' represents the number 3, the last parameter is ignored.

Abstract (TLDR)

[ '1', '7', '11']. Map (parseInt) does not work as expected, because the map is transmitted to the three parameters in each iteration parseInt (). The second parameter index is passed as the radix (binary) parameter to parseInt. Thus, using different binary (base) parsing each string array. '7' is interpreted as binary (base) is 1, it is a NaN, '11 'is interpreted as binary (base) 2, which is 3,' 1 'is interpreted as the default binary (base ) is 10, because its index of 0 is false.

I do not know if you would like to see no

Reproduced in: https: //juejin.im/post/5d0202da51882546dd10087b

Guess you like

Origin blog.csdn.net/weixin_34413065/article/details/93163628