In our daily development, operating and converting arrays is a very common operation. Let's take a look at an example:
The code copy is as follows:
var desColors = [],
srcColors = [
{r: 255, g: 255, b: 255 }, // White
{r: 128, g: 128, b: 128 }, // Gray
{r: 0, g: 0, b: 0 } // Black
];
for (var i = 0, ilen = srcColors.length; i < ilen; i++) {
var color = srcColors[i],
format = function(color) {
return Math.round(color / 2);
};
desColors.push( {
r: format(color.r),
g: format(color.g),
b: format(color.b)
});
}
// Outputs:
// [
// {r: 128, g: 128, b: 128 },
// {r: 64, g: 64, b: 64 },
// {r: 0, g: 0, b: 0 }
// ];
console.log(desColors);
From the above example, we can see that all operations have a relatively high repetition rate. How to optimize it? Fortunately, Ecmascript 5 provides us with a map method, which we can use to optimize the above example:
The code copy is as follows:
var srcColors = [
{r: 255, g: 255, b: 255 }, // White
{r: 128, g: 128, b: 128 }, // Gray
{r: 0, g: 0, b: 0 } // Black
],
desColors = srcColors.map(function(val) {
var format = function(color) {
return Math.round(color/2);
};
return {
r: format(val.r),
g: format(val.g),
b: format(val.b)
}
});
// Outputs:
// [
// {r: 128, g: 128, b: 128 },
// {r: 64, g: 64, b: 64 },
// {r: 0, g: 0, b: 0 }
// ];
console.log(desColors);
From the above example, we can see that we used map to replace the for loop part, so that we only need to care about the implementation logic of each element itself. For details about the map method, please click here.
1. Map basic definition:
array.map(callback[, thisArg]);
The map method calls the callback function once in order for each element in the original array. callback The return values after each execution are combined to form a new array. The callback function will only be called on indexes with value; indexes that have never been assigned values or deleted with delete will not be called.
The callback function will be automatically passed in three parameters: array element, element index, and the original array itself.
If thisArg parameter has a value, this will point to this object on thisArg parameter every time the callback function is called. If the thisArg parameter is omitted, or the value is assigned to null or undefined, this points to the global object.
map does not modify the original array itself that calls it (of course, it can change the original array when the callback is executed).
When an array runs a map method, the length of the array is determined before the first callback method is called. During the entire operation of the map method, no matter whether the operations in the callback function add or delete elements to the original array. The map method will not know. If the array element increases, the newly added element will not be traversed by the map. If the array element decreases, the map method will also think that the length of the original array has not changed, resulting in the array access to the outbound. If elements in the array are changed or deleted, the value they are passed into callback is the value of the map method traversing to their moment.
2.map instance:
The code copy is as follows:
//Example 1: Call map method on string
var result = Array.prototype.map.call("Hello world", function(x, index, arr) {
//String {0: "H", 1: "e", 2: "l", 3: "l", 4: "o", 5: " ", 6: "w", 7: "o", 8: "r", 9: "l", 10: "d", length: 11}
console.log(arr);
return x.charCodeAt(0);
});
//Outputs: [72, 101, 108, 108, 111, 32, 119, 111, 114, 108, 100]
console.log(result);
The above example demonstrates using the map method on a String to obtain an array of ASCII codes corresponding to each character in a string. Please pay attention to the print results of console.log(arr) printed.
The code copy is as follows:
//Example 2: What is the result of the following operation?
var result = ["1", "2", "3"].map(parseInt);
//Outputs: [1, NaN, NaN]
console.log(result);
Maybe you will have a question, why not [1,2,3]? We know that the parseInt method can receive two parameters. The first parameter is the value that needs to be converted, and the second parameter is the number of the binary. If you don’t understand, you can click here. When we use the map method, the callback function receives three parameters, while parseInt can only receive two parameters at most, so that the third parameter is directly discarded. At the same time, parseInt uses the passed index value as a binary number, thus returning NaN. Look at the following output results:
The code copy is as follows:
//Ouputs: 1
console.log(parseInt("1", 0));
//Ouputs: 1
console.log(parseInt("1", undefined));
//Ouputs: NaN
console.log(parseInt("2", 1));
//Ouputs: NaN
console.log(parseInt("3", 2));
The last two are easy to understand, but why do the first two return 1? To explain this issue, let's take a look at the official description:
If radix is undefined or 0 (or absent), JavaScript assumes the following:
a) If the input string begins with “0x” or “0X”, radix is 16 (hexadecimal) and the remainder of the string is parsed.
b) If the input string begins with “0″, radix is eight (octal) or 10 (decimal). Exactly which radix is chosen is implementation-dependent. ECMAScript 5 specifications that 10 (decimal) is used, but not all browsers support this yet. For this reason always specify a radix when using parseInt.
c) If the input string begins with any other value, the radix is 10 (decimal).
In the third point, when string is another value, the default is 10.
So how do we modify it to make the above example output normally? See the following example:
The code copy is as follows:
var result = ["1", "2", "3"].map(function(val) {
return parseInt(val, 10);
});
//Outputs: [1, 2, 3]
console.log(result);
3. Map method compatibility:
The map method is not supported in IE8 and below browsers. If you want to be compatible with older versions of browsers, you can:
a) Don't use map .b) Use something like es5-shim to make older IE's support map .c) Use the _.map method in Underscore or Lodash for an equivalent utility function.
The above is the understanding of the map method. I hope it will be helpful to beginners. If there are any inappropriate points in the article, I hope you can correct it!