JavaScript Array.map() 的 5 种用途

首先与 forEach() 会改变操作数组不同,.map() 是一种 non-mutating(非变异) 方法,它创建一个新数组,而不是只对调用数组进行更改的 mutating(变异) 方法。

1. 对数组中的每项元素调用函数

这是最基本的用法,不多说。简单看下例子

let exampleArray = [2, 3, 4, 5, 6];
let doubleArray = exampleArray.map(item => item * 2)

console.log(exampleArray ); // [2, 3, 4, 5, 6]
console.log(doubleArray);  // [4, 6, 8, 10, 12]

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 这样的JS库中利用 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 中的一个简单的无状态组件,它使用列表渲染div。 使用 .map() 渲染单个列表项以迭代最初创建的 names 数组。 此组件使用 ReactDOM 渲染 ID为 root 的 DOM 元素 。

重新格式化数组对象

如何处理数组中的对象? .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.小技巧使用案例

生成新数组元素的 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);

等同于

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
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 158,560评论 4 361
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,104评论 1 291
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,297评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,869评论 0 204
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,275评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,563评论 1 216
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,833评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,543评论 0 197
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,245评论 1 241
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,512评论 2 244
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,011评论 1 258
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,359评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,006评论 3 235
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,062评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,825评论 0 194
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,590评论 2 273
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,501评论 2 268

推荐阅读更多精彩内容