你应该了解的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 相关文章推荐
javascript 写类方式之五
Jul 05 Javascript
javascript 进度条 实现代码
Jul 30 Javascript
JavaScript 精粹读书笔记(1,2)
Feb 07 Javascript
基于jquery的大众点评,分类导航实现代码
Aug 23 Javascript
DIV外区域Click后关闭DIV的实现代码
Dec 21 Javascript
jquery下div 的resize事件示例代码
Mar 09 Javascript
AngularJS实现根据不同条件显示不同控件
Apr 20 Javascript
vue发送ajax请求详解
Oct 09 Javascript
webpack-url-loader 解决项目中图片打包路径问题
Feb 15 Javascript
仿vue-cli搭建属于自己的脚手架的方法步骤
Apr 17 Javascript
layui实现根据table数据判断按钮显示情况的方法
Sep 26 Javascript
HTML+JavaScript实现扫雷小游戏
Sep 30 Javascript
微信小程序中的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
php5中类的学习
2008/03/28 PHP
php文件夹与文件目录操作函数介绍
2013/09/09 PHP
PHP获取当前相对于域名目录的方法
2015/06/26 PHP
jquery根据属性和index来查找属性值并操作
2014/07/25 Javascript
JavaScript中的依赖注入详解
2015/03/18 Javascript
jQuery Form 表单提交插件之formSerialize,fieldSerialize,fieldValue,resetForm,clearForm,clearFields的应用
2016/01/23 Javascript
探讨JavaScript语句的执行过程
2016/01/28 Javascript
简单模拟node.js中require的加载机制
2016/10/27 Javascript
JavaScript实现Fly Bird小游戏
2016/12/15 Javascript
BootStrap学习系列之布局组件(下拉,按钮组[toolbar],上拉)
2017/01/03 Javascript
JavaScript正则表达式替换字符串中图片地址(img src)的方法
2017/01/13 Javascript
vue-cli入门之项目结构分析
2017/04/20 Javascript
Vue 滚动行为的具体使用方法
2017/09/13 Javascript
[49:07]VGJ.T vs Optic Supermajor小组赛D组 BO3 第二场 6.3
2018/06/04 DOTA
python启动办公软件进程(word、excel、ppt、以及wps的et、wps、wpp)
2009/04/09 Python
python批量下载图片的三种方法
2013/04/22 Python
Python中endswith()函数的基本使用
2015/04/07 Python
python中文件变化监控示例(watchdog)
2017/10/16 Python
Python元字符的用法实例解析
2018/01/17 Python
对Python中type打开文件的方式介绍
2018/04/28 Python
Python基于SMTP协议实现发送邮件功能详解
2018/08/14 Python
Python 使用类写装饰器的小技巧
2018/09/30 Python
Python2和Python3之间的str处理方式导致乱码的讲解
2019/01/03 Python
Python字典生成式、集合生成式、生成器用法实例分析
2020/01/07 Python
Nuts.com:优质散装,批发坚果、干果和巧克力等
2017/03/21 全球购物
最畅销的视频游戏享受高达90%的折扣:CDKeys
2020/02/10 全球购物
创业计划书中要认真思考的问题
2013/12/28 职场文书
《红军不怕远征难》教学反思
2014/04/14 职场文书
寒假家长评语大全
2014/04/16 职场文书
体操比赛口号
2014/06/10 职场文书
传播学专业毕业生自荐书
2014/07/01 职场文书
高考学习决心书
2015/02/04 职场文书
餐馆开业致辞
2015/08/01 职场文书
css实现左上角飘带效果的完整代码
2022/03/18 HTML / CSS
Linux系统下MySQL配置主从分离的步骤
2022/03/21 MySQL
Beekeeper Studio开源数据库管理工具比Navicat更炫酷
2022/06/21 数据库