你应该了解的JavaScript Array.map()五种用途小结


Posted in Javascript onNovember 14, 2018

前言

从经典的 for 循环到 forEach() 方法,用于迭代数据集合的各种技术和方法比比皆是。但是现在比较流行的方法是 .map() 方法。

.map() 通过指定函数调用一个数组中每一项元素,来创建一个新数组。 .map() 是一种 non-mutating(非变异) 方法,它创建一个新数组,而不是只对调用数组进行更改的 mutating(变异) 方法。这可能很难记住。

语法:

array.map(function(currentValue,index,arr), thisValue)
  • currentValue:必须。当前元素的值
  • index:可选。当期元素的索引值
  • arr:可选。当期元素属于的数组对象
  • thisValue:可选。对象作为该执行回调时使用,传递给函数,用作 "this" 的值。可改变this指向,

map() 方法返回一个新数组,数组中的元素为原始数组元素调用函数处理后的值。

map() 方法按照原始数组元素顺序依次处理元素。

注意: map() 不会对空数组进行检测。

注意: map() 不会改变原始数组。

在这篇文章中,我们将探讨一下 JavaScript 中 .map() 的 4 个值得注意的用法。让我们开始!

  • 在数组中的每一项元素上调用一个函数
  • 将字符串转换为数组
  • 在 JavaScript 库中用于渲染列表
  • 重新格式化数组对象
  • 小技巧使用案例

1. 在数组中的每一项元素上调用一个函数

如前所述,.map() 接受回调函数作为其参数之一,该函数的一个重要参数是由该函数处理的项的当前值。这是一个必需的参数。有了这个参数,我们可以修改数组中的每个单独项,并在其上创建一个新元素。这里有一个例子:

const sweetArray = [2, 3, 4, 5, 35]
const sweeterArray = sweetArray.map(sweetItem => {
return sweetItem * 2
})

console.log(sweetArray) // [2, 3, 4, 5, 35]
console.log(sweeterArray) // [4, 6, 8, 10, 70]

我们可以看到,原数组 sweetArray 并没有被修改,所以 .map() 是一种 non-mutating(非变异) 方法。这里值得一提的是 forEach() 方法,它是遍历数组,对原来的数据操作,会改变原数组。

这甚至可以进一步简化,使其更清洁:

// 创建一个要使用的函数
const makeSweeter = sweetItem => sweetItem * 2;

// 我们有一个数组
const sweetArray = [2, 3, 4, 5, 35];

// 调用我们制作的函数。更具可读性
const sweeterArray = sweetArray.map(makeSweeter);

console.log(sweeterArray); // [4, 6, 8, 10, 70]

拥有像 sweetArray.map(makeSweeter) 这样的代码可以让你在跳转到这段代码时更具可读性。

2.将字符串转换为数组

已知的 .map() 属于 Array 原型。 我们如何使用它将字符串转换为数组。 不用担心,我们不需要再开发一个方法来处理字符串,而是使用特殊的 .call() 方法。

JavaScript 中的所有内容都是对象,方法只是附加到这些对象的函数。 .call() 允许我们利用另一个对象的上下文。 因此,我们将数组中的 .map() 上下文复制到字符串。

.call() 可以传递参数,要使用的上下文和“参数原始函数的参数”。 听起来有点拗口? 这是一个例子:

const name = "Chuloo"
const map = Array.prototype.map

const newName = map.call(name, eachLetter => {
return `${eachLetter}a`
})

console.log(newName) // ["Ca", "ha", "ua", "la", "oa", "oa"]

这里,我们只是在String上使用 .map() 的上下文,并传递了 .map() 所期望的函数参数。 你可以看看控制台里打印出来的内容。

这类似于 String 的 .split() 方法,不过 .split() 方法只能在返回数组之前修改每个单独的字符串字符。

3.在 JavaScript 库中用于渲染列表

像 React 这样的 JavaScript 库利用 .map() 来渲染列表中的项目。这需要 JSX 语法,但是 .map() 方法包含在类似于 mustache 的 JSX 语法中。这是 React 组件的一个很好的例子。

import React from "react";
import ReactDOM from "react-dom";

const names = ["john", "sean", "mike", "jean", "chris"];

const NamesList = () => (
<div>
<ul>{names.map(name => <li key={name}> {name} </li>)}</ul>
</div>
);

const rootElement = document.getElementById("root");
ReactDOM.render(<NamesList />, rootElement);

如果你不熟悉 React ,那么我告诉这是 React 中的一个简单的无状态组件,它使用列表渲染div。 使用 .map() 渲染单个列表项以迭代最初创建的 names 数组。 此组件使用 ReactDOM 渲染 ID为 root 的 DOM 元素 。

4.重新格式化数组对象

如何处理数组中的对象? .map() 可用于迭代数组中的对象,并以与传统数组类似的方式,修改每个单独对象的内容 并返回一个新数组。 这个修改是基于回调函数中返回的内容来完成的。这里有一个例子:

const myUsers = [
{ name: 'chuloo', likes: 'grilled chicken' },
{ name: 'chris', likes: 'cold beer' },
{ name: 'sam', likes: 'fish biscuits' }
]

const usersByFood = myUsers.map(item => {
const container = {};

container[item.name] = item.likes;
container.age = item.name.length * 10;

return container;
})


console.log(usersByFood);
// [{chuloo: "grilled chicken", age: 60}, {chris: "cold beer", age: 50}, {sam: "fish biscuits", age: 30}]

我们所做的就是使用括号和点符号简单地修改数组中的每个对象。这个用例可以用于在前端应用程序上保存或解析之前处理或压缩接收到的数据。

5.小技巧使用案例

通常情况下,.map() 方法中的 callback 函数只需要接受一个参数,就是正在被遍历的数组元素本身。但这并不意味着 map 只给 callback 传了一个参数。这个思维惯性可能会让我们犯一个很容易犯的错误。 生成新数组元素的 callback 函数,有 三个参数:

  • currentValue ? callback 的第一个参数,数组中正在处理的当前元素,最常用的参数。
  • index ? callback 的第二个参数,数组中正在处理的当前元素的索引。
  • array ? callback 的第三个参数,map 方法被调用的数组。

来看一下例子:

// 下面的语句返回什么呢:
["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]

还有一个非常实用的小技巧,像 .map() ,.reduce(), .filter() 这些方法支持链式调用。例如:

var myArr = [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ];

var result = myArr
.map(function(element) {
// 数值大于5的数值视为5
if (element > 5)
return 5;

return element;
})
.reduce(function(prev, element) {
// 与之前的数值加总,回传后代入下一轮的处理
return prev + element;
}, 0);

// 40
console.log(result);

这代码看着有点??率前桑扛行 pythonicx 提供的优化代码:

var myArr = [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ];
let result = myArr.map(m => m>5 ? 5 : m).reduce((x,y) => x+y);
console.log(result); // 40

小结

在这篇文章中,我们研究了 JavaScript 中 .map() 方法的主要用途。 需要注意的是,与其他方法结合使用时,.map() 的函数可以得到强大的扩展和利用。 尝试找出更多用例。

Javascript 相关文章推荐
20个最新的jQuery插件
Jan 13 Javascript
Jquery实现鼠标移上弹出提示框、移出消失思路及代码
May 19 Javascript
javascript实现模拟时钟的方法
May 13 Javascript
深入探讨javascript函数式编程
Oct 11 Javascript
理解javascript模块化
Mar 28 Javascript
bootstrap多种样式进度条展示
Dec 20 Javascript
详解AngularJS 模块化
Jun 14 Javascript
详解使用Next.js构建服务端渲染应用
Jul 10 Javascript
微信小程序实现Session功能及无法获取session问题的解决方法
May 07 Javascript
微信小程序wx.request拦截器使用详解
Jul 09 Javascript
基于layui轮播图满屏是高度自适应的解决方法
Sep 16 Javascript
jquery实现手风琴案例
May 04 jQuery
微信小程序中的canvas 文字断行和省略号显示功能的处理方法
Nov 14 #Javascript
Vue 框架之动态绑定 css 样式实例分析
Nov 14 #Javascript
js删除对象/数组中null、undefined、空对象及空数组方法示例
Nov 14 #Javascript
Vue 框架之键盘事件、健值修饰符、双向数据绑定
Nov 14 #Javascript
Vue源码探究之状态初始化
Nov 14 #Javascript
vue使用laydate时间插件的方法
Nov 14 #Javascript
js使用Promise实现简单的Ajax缓存
Nov 14 #Javascript
You might like
如何冲泡挂耳包咖啡?技巧是什么
2021/03/04 冲泡冲煮
php读取xml实例代码
2010/01/28 PHP
jQuery+php实现ajax文件即时上传的详解
2013/06/17 PHP
php实现图片上传并进行替换操作
2016/03/15 PHP
Docker搭建自己的PHP开发环境
2018/02/24 PHP
Laravel框架实现多个视图共享相同数据的方法详解
2019/07/09 PHP
js过滤数组重复元素的方法
2010/09/05 Javascript
jQuery制作拼图小游戏
2015/01/12 Javascript
JS从数组中随机取出几个数组元素的方法
2016/08/02 Javascript
vue中用动态组件实现选项卡切换效果
2017/03/25 Javascript
Node.js实现注册邮箱激活功能的方法示例
2018/03/23 Javascript
原生js实现的金山打字小游戏(实例代码详解)
2020/03/16 Javascript
jquery.validate自定义验证用法实例分析【成功提示与择要提示】
2020/06/06 jQuery
python读取浮点数和读取文本文件示例
2014/05/06 Python
Python内置数据类型详解
2014/08/18 Python
Python通过PIL获取图片主要颜色并和颜色库进行对比的方法
2015/03/19 Python
Python简单遍历字典及删除元素的方法
2016/09/18 Python
利用Python脚本实现ping百度和google的方法
2017/01/24 Python
python 用lambda函数替换for循环的方法
2018/06/09 Python
Python爬虫使用脚本登录Github并查看信息
2018/07/16 Python
python实现转盘效果 python实现轮盘抽奖游戏
2019/01/22 Python
python-itchat 统计微信群、好友数量,及原始消息数据的实例
2019/02/21 Python
Python HTTP下载文件并显示下载进度条功能的实现
2020/04/02 Python
支持IE8的纯css3开发的响应式设计动画菜单教程
2014/11/05 HTML / CSS
将HTML5 Canvas的内容保存为图片借助toDataURL实现
2013/05/20 HTML / CSS
老师给学生的表扬信
2014/01/17 职场文书
篝火晚会主持词
2014/03/25 职场文书
银行求职信
2014/05/31 职场文书
体育比赛口号
2014/06/09 职场文书
销售团队获奖感言
2014/08/14 职场文书
处级干部反四风个人对照检查材料思想汇报
2014/09/27 职场文书
2015年度服装销售工作总结
2015/03/31 职场文书
2015年材料员工作总结
2015/04/30 职场文书
python 定义函数 返回值只取其中一个的实现
2021/05/21 Python
Redis如何实现分布式锁
2021/08/23 Redis
Java 定时任务技术趋势简介
2022/05/04 Java/Android