你应该了解的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 相关文章推荐
拖动table标题实现改变td的大小(css+js代码)
Apr 16 Javascript
解决jQuery uploadify在非IE核心浏览器下无法上传
Aug 05 Javascript
JS实现slide文字框缩放伸展效果代码
Nov 05 Javascript
window.setInterval()方法的定义和用法及offsetLeft与style.left的区别
Nov 11 Javascript
XML、HTML、CSS与JS的区别整理
Feb 18 Javascript
JavaScript SHA-256加密算法详细代码
Oct 06 Javascript
JavaScript实现Fly Bird小游戏
Dec 15 Javascript
jQuery点击导航栏选中更换样式的实现代码
Jan 23 Javascript
jQuery加密密码到cookie的实现代码
Apr 18 jQuery
使用jQuery实现两个div中按钮互换位置的实例代码
Sep 21 jQuery
详述 Sublime Text 打开 GBK 格式中文乱码的解决方法
Oct 26 Javascript
vue中的.$mount('#app')手动挂载操作
Sep 02 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
PHP+Mysql+jQuery实现动态展示信息
2011/10/08 PHP
php 解决旧系统 查出所有数据分页的类
2012/08/27 PHP
PHP+memcache实现消息队列案例分享
2014/05/21 PHP
php通过正则表达式记取数据来读取xml的方法
2015/03/09 PHP
PHP通过加锁实现并发情况下抢码功能
2016/08/10 PHP
javascript学习笔记(十四) window对象使用介绍
2012/06/20 Javascript
jQuery 鼠标经过(hover)事件的延时处理示例
2014/04/14 Javascript
jquery进行数组遍历如何跳出当前的each循环
2014/06/05 Javascript
BOOTSTRAP时间控件显示在模态框下面的bug修复
2015/02/05 Javascript
js实现缓冲运动效果的方法
2015/04/10 Javascript
JavaScript代码判断点击第几个按钮
2015/12/13 Javascript
基于jQuery Ajax实现上传文件
2016/03/24 Javascript
让html元素随浏览器的大小自适应垂直居中的实现方法
2016/10/12 Javascript
vue表单绑定实现多选框和下拉列表的实例
2017/08/12 Javascript
微信小程序授权获取用户详细信息openid的实例详解
2017/09/20 Javascript
微信小程序传值以及获取值方法的详解
2019/04/29 Javascript
解决layui页面按钮点击无反应,也不报错的问题
2019/09/29 Javascript
Vue解析带html标签的字符串为dom的实例
2019/11/13 Javascript
Python实现读取并保存文件的类
2017/05/11 Python
基于python的ini配置文件操作工具类
2019/04/24 Python
python实现京东订单推送到测试环境,提供便利操作示例
2019/08/09 Python
Python常用数字处理基本操作汇总
2020/09/10 Python
Python3使用Selenium获取session和token方法详解
2021/02/16 Python
pycharm 使用tab跳出正在编辑的括号(){}{}等问题
2021/02/26 Python
css3实现的多级渐变下拉菜单导航效果代码
2015/08/31 HTML / CSS
HTML5实现桌面通知 提示功能
2017/10/11 HTML / CSS
美国美妆网站:B-Glowing
2016/10/12 全球购物
美国一家主打母婴用品的团购网站:zulily
2017/09/19 全球购物
Viking比利时:购买办公用品
2019/10/30 全球购物
干部下基层实施方案
2014/03/14 职场文书
护士求职自荐信范文
2014/03/19 职场文书
爱国口号
2014/06/19 职场文书
学生党员一帮一活动总结
2014/07/08 职场文书
先进教师个人总结
2015/02/11 职场文书
老龙头导游词
2015/02/11 职场文书
Go语言带缓冲的通道实现
2021/04/26 Golang