最近看mdn中 Array.prototype.map,以下为看的总结点
Array.prototype.map() 简介 map()方法创建一个新数组,其结果是该数组中每个元素都调用一个提供的函数后返回的结果 举例如下:
1 2 3 4 5 6 var Array1 = [1, 4, 9, 6]; // pass a function to map const map1 = array1.map(x => x * 2); console.log(map1); // expected output: [2, 8, 18, 12]
语法 1 2 3 var newArray = arr.map(function callback(currentValue[, index[, array]])) { return element for new_array }[, thisArg]);
参数
生成新的数组函数,使用三个参数
callback数组中正在处理的当前元素.
(可选) callback 数组中正在处理的当前元素的索引.
(可选)执行callback函数时使用的this值。
返回值 一个新数组,每个元素都是回调函数的结果。
描述 map方法会给原数组中的每个元素都按顺序调用一次callback函数。callback每次执行后的返回值(包括undefined)组合起来形成一个新数组。callback函数只会在有值的索引上被调用;那些从来没被赋过值或者使用delete删除的索引则不会被调用。 callback 函数会被自动传入三个参数:数组元素、元素索引、原数组本身。 如果thisArg参数有值,则每次callback函数被调用的时候,this都会指向thisArg参数上的这个对象.如果省略了thisArg参数,后者赋值为null活undefined,则this指向全局对象。 map不修改调用它的原数组本身(当然可以在callback执行时改变原数组). 使用map方法处理数组时,数组元素的范围在callback方法第一次调用之前就已经确定了。在map方法执行的过程中:原数组中新增加的元素将不会被callback访问到;若已经存在的元素被改变或删除了,则他们的传递到callback的值map方法便利到它们的那一时刻的值;而被删除的元素不会被访问到。
示例 求数组中每个元素的平方根 下面的代码创建了一个新数组,值为原数组中对应数字的平方根
1 2 3 var numbers = [1, 4, 9]; var roots = numbers.map(Math.sqrt); // roots的值为[1,2,3], numbers的值仍为[1,4,9]
使用map重新格式化数组中的对象 以下代码使用一个包含对象的数组来重新创建一个格式化的数组.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 var kvArray = [{key: 1, value: 10}, {key: 2, value: 20}, {key: 3, value: 30}, ]; var reformattedArray = kvArray.map(function (obj) { var rObj = {}; rObj[obj.key] = obj.value; return rObj; }); // reforamttedArray 数组为: [{1: 10}, {2: 20}, {3: 30}]; // kvArray 数组未被修改 // [{key: 1, value: 10}, // {key: 2, value: 20}, // {key: 3, value: 30}]
使用一个包含一个参数的函数来mapping(构建)一个数字数组 下面的代码表示了当函数需要一个参数时map的工作方式。当map循环便利原始数组时,这个参数回自动被分配成数组中对应的每个元素。
1 2 3 4 5 6 7 var numbers = [1, 4, 9]; var doubles = numbers.map(function (item) => { return num * 2; }); // doubles数组的值为: [2, 8, 18]; // numbers数组未被修改 [1, 4, 9]
一般的map方法 下面的例子演示如何在一个String上使用map方法获取字符串中每个字符多对应的ASCII码组成的数组。
1 2 3 4 var map = Array.prototype.map; var a = map.call('Hello World' , function (x) { return x.charCodeAt(0); });
querySelectorAll 应用 下面代码展示了如何去遍历用querySelectorAll 得到的动态对象集合。在这里,我们获得了文档里所有选中的选项,并将其打印:
1 2 3 4 var elems =document.querySelectorAll('select option:checked' ); var values = Array.prototype.map.call(elems. function (obj) { return obj.value; });
使用技巧案例 通常情况下,map方法中的callback函数只需要接受一个参数,就是正在被遍历的数组元素本身。但这并不意味着map只给callback传了一个参数。这个思维惯性可能会让我们犯一个很容易犯的错误。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 // 下面的语句返回什么呢: ['1' , '2' , '3' ].map(parseInt); // 你可能觉得会是 [1, 2, 3]; // 但实际结果是[1, NaN, NaN]; // 通常使用parseInt时,只需要传递一个参数 // 但实际上,parseInt可以有两个参数,第二个参数是进制数 // 可以通过语句 'alert(parseInt.length) === 2' 来验证 // map方法在调用callback函数时,会给它传递三个参数:当前正在遍历的元素,元素索引,原数组本身。 // 第三个参数parseInt 会忽视,但第二个参数不会,也就是说,parseInt把传过来的索引值当成进制数来使用,从而返回了NaN function returnInt (element) { return parseInt(element, 10); } ['1' , '2' , '3' ].map(returnInt); // [1, 2, 3] 意料之中的结果 // 也可以使用简单的箭头函数,结果同上 ['1' , '2' , '3' ].map( str => parseInt(str)); // 一个简单的方式: ['1' , '2' , '3' ].map(Number); // [1, 2, 3] // 与`parseInt`不同,下面的结果会返回浮点数或指数 ['1.1' , '2.2e2' , '3e300' ].map(Number); // [1.1, 220, 3e+300]
Polyfill map是在最近的ECMA-262 标准中新添加的方法;所以一些旧版本的浏览器可能没有实现该方法。在那些没有原生支持map方法的浏览器中,你可以使用下面的Javascript代码来实现它。所使用的算法正式ECMA-262,第五版规定的。假定Object,TypeError, 和Array有他们的原始值。而且callback.call的原始值也是Function.prototype.call
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 // 实现ECMA-262, Edition 5,15.4.4.19 //参考: http://es5.github/com/ if (!Array.prototype.map) { Array.prototype.map = function (callback, thisArg) { var T,A,k; if (this == null) { throw new TypeError(' this is null or not defined' ); } // 1.将0赋值为调用map方法的数组 var 0 = Object(this); // 2.将len赋值为数组0的长度 var len = 0.length >>> 0; // 3.如果callback 不是函数,则跑出TypeError异常 if (Object.prototype.toString.call(callback) != '[object Function]' ) { throw new TypeError(callback + ' is not a function' ); } // 4. 如果参数thisArg有值,则将T赋值为thisArg; if (thisArg) { T = thisArg; } // 5. 创建新数组A,长度为原数组0长度len A = new Array(len); // 6. 将k赋值为0 k = 0; // 7. 当k < len时,执行循环 while (k < len) { var kValue, mappedValue; // 遍历0,k为原数组索引 if (k in 0) { // kValue为索引k对应的值 kValue = 0[k]; // 执行callback,this指向T,参数有三个,分别是kValue:值,k:索引,0:原数组 mappedValue = callback.call(T,kValue,k,0); // 返回值添加到新数组A中 A[k] = mappedValue; } // k自增1 k ++; } // 返回新数组 return A; }; }