深入理解 Array.prototype.map()
2018-03-14 14:32
120 查看
深入理解 Array.prototype.map()
map()方法创建一个新数组,其结果是该数组中的每个元素都调用一个提供的函数后返回的结果。
语法
let new_array = arr.map(function callback(currentValue, index, array) { // Return element for new_array }[, thisArg])
参数
callback生成新数组元素的函数,使用三个参数:
currentValue数组中正在处理的当前元素。
index数组中正在处理的当前元素的索引。
arraymap 方法被调用的数组。
thisArg可选的。执行
callback函数时 使用的
this值。
实际应用
使用指定的方法对数组做批处理
原理var numbers = [1, 4, 9]; var roots = numbers.map(Math.sqrt); console.log(numbers) // [1, 4, 9] console.log(roots) // [1, 2, 3]
封装
var numbers = [1, 4, 9]; const arrBat = (arr, func) => arr.map(func) var roots = arrBat(numbers, Math.sqrt) console.log(numbers) // [1, 4, 9] console.log(roots) // [1, 2, 3]
只需要传入对应的处理方法,即可对数组所有元素做批处理。
当然也可对此方法进行二次封装:
var numbers = [1, 4, 9]; const arrBat = (arr, func) => arr.map(func) const arrToSqrt = (arr) => arrBat(arr, Math.sqrt) // 开平方根 const arrToSquare = (arr) => arrBat(arr, e => Math.pow(e, 2)) // 平方 const arrToRound = (arr) => arrBat(arr, Math.round) // 四舍五入 const arrToCeil = (arr) => arrBat(arr, Math.ceil) // 求上整 const arrToFloor = (arr) => arrBat(arr, Math.floor) // 求下整 const arrToDouble = (arr) => arrBat(arr, e => 2 * e) // 求倍数 arrToSquare(numbers) // [1, 16, 81] arrToSqrt(numbers) // [1, 2, 3]
多参数函数批量转化的误区
先看下面一个方法:["1", "2", "3"].map(parseInt);
第一反应,这里应该返回的是
[1, 2, 3],然而,实际上返回的却是
[1, NaN, NaN]。
这是为什么呢?
事实上,
parseInt接收两个参数,第一个是原始值,第二个是进制值,通常我们使用
parseInt('5')类似的操作,实际上是默认第二参数为 10,。但注意,在
map回调函数中,有三个参数,第一个是遍历出来的每一个元素,第二参数为遍历出的元素的下标,第三参数为调用者本身。这里,
parseInt接到了
map的前两个参数,也就是元素和下标,第三参数被忽略,
parseInt把传过来的索引值当成进制数来使用,从而返回了NaN。
正确的做法是:
const arrToInt = str => Array.prototype.map.call(str, e => parseInt(e, 10)) arrToInt("57832") // [5, 7, 8, 3, 2] arrToInt([1.2, 3.4, 9.6]) // [1, 3, 9]
与
parseInt不同,下面的结果会返回浮点数或指数 :
['1.1', '2.2e2', '3e300'].map(Number); // [1.1, 220, 3e+300]
使用 map 重新格式化数组中的对象
原理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; }); // [{1: 10}, {2: 20}, {3: 30}],
封装
var kvArray = [{key: 1, value: 10}, {key: 2, value: 20}, {key: 3, value: 30}] kvArrayToObjArray = (obj) => obj.map(e => { var rArr = []; rArr.push(e.key, e.value); return rArr; }) var reformattedArray = kvArrayToObjArray(kvArray) // [[1, 10], [2, 20], [3, 30]]
反转字符串
原理var str = 'Hello'; Array.prototype.map.call(str, function(x) { return x; }).reverse().join(''); // 'olleH'
封装
const reverseStr = str => Array.prototype.map.call(str, e => e).reverse().join('') c = reverseStr('Hello') // 'olleH'
当然,还有一个更简单的反转字符串方法,使用 ES6 的解构即可
const reverseString = str => [...str].reverse().join(''); reverseString('foobar') // 'raboof'
将字符串转换为 ASCII 码
原理var a = Array.prototype.map.call("Hello World", function(x) { return x.charCodeAt(0); }) // [72, 101, 108, 108, 111, 32, 87, 111, 114, 108, 100]
封装
const strToAscii = str => Array.prototype.map.call(str, e => e.charCodeAt(0)) strToAscii("Hello World") // [72, 101, 108, 108, 111, 32, 87, 111, 114, 108, 100]
DOM 操作
甚至可以使用 map 对 DOM 进行操作var elems = document.querySelectorAll('select option:checked'); var values = Array.prototype.map.call(elems, function(obj) { return obj.value; });
相关文章推荐
- 深入理解golang — 数组(array)、切片(slice)、map
- 深入理解javascript原型和闭包(3)——prototype原型
- 深入理解Spark 2.1 Core (十):Shuffle Map 端的原理与源码分析
- map方法学习,封装函数--实现Array.prototype.map()的功能
- java的集合框架set 和map的深入理解
- 深入理解js的prototype以及prototype的一些应用
- [置顶] 深入理解javascript原型和闭包(3)——prototype原型
- 深入理解Java集合之Map
- Array.prototype.map()方法详解
- 深入理解javascript原型和闭包(3)——prototype原型
- 深入理解java映射map的底层操
- 【深入理解java集合系列】List,Set,Map用法以及区别
- 深入理解javascript原型和闭包(3)——prototype原型
- 对Array.prototype.slice.call的理解
- Java Thread&Concurrency(16): 深入理解ArrayBlockingQueue及其实现原理
- list,map,array理解
- 深入理解Spark 2.1 Core (十):Shuffle Map 端的原理与源码分析
- JavaScript中__proto__与prototype的关系深入理解
- NodeList 借用call方法使用Array.prototype.map方法
- 深入理解ConcurrentMap.putIfAbsent(key,value) 用法