译者按: 做一个有追求的工程师,代码不是随便写的!

为了保证可读性,本文采用意译而非直译。另外,本文版权归原作者所有,翻译仅用于学习。

小编推荐:Fundebug专注于JavaScript、微信小程序、微信小游戏,Node.js和Java线上bug实时监控。真的是一个很好用的bug监控服务,众多大佬公司都在使用。

我保证这是一篇可以快速阅读并吸收的文章。在过去的几个月里,我检查的所有的pull request中,都犯了这4个的错误。我写这篇文章的另一个原因在于我自己也犯过这些错。我们来看看如何正确地使用它们!

1. 不要使用Array.indexOf,使用Array.includes

“如果你要在数组中查找元素,使用Array.indexOf!”。记得在我学习JavaScript课程时候,有这样一句话。这句话没错,确实可以这么使用!

根据MDN文档:“Array.indexOf会返回被查找元素第一个匹配的位置的下标。”因此,如果后面需要用到这个索引,Array.indexOf是一个很好的解法。

但是,我们要解决的问题是:查找数组中是否包含某个元素。这是一个Yes/No的问题,是一个返回布尔类型的真假问题。因此,我建议使用Array.includes,它会返回一个布尔值。

'use strict';

const characters = [
'ironman',
'black_widow',
'hulk',
'captain_america',
'hulk',
'thor',
]; console.log(characters.indexOf('hulk'));
// 2
console.log(characters.indexOf('batman'));
// -1 console.log(characters.includes('hulk'));
// true
console.log(characters.includes('batman'));
// false

2. 不要使用Array.filter,使用Array.find

Array.filter是一个很有用的函数,它返回一个满足过滤条件的新数组。正如其名字表达的含义,它是用来做过滤的。

但是,如果我们知道我们要的结果只有一个元素的时候,我就不建议使用它了。比如,如果我们的回调函数定义用一个唯一的ID来过滤,那么结果必然唯一了。在这个情况下,Array.filter会返回只有一个元素的数组。因为既然能通过一个特定的ID来查找,我们已经确定只有一个元素了,那么使用数组就没有意义。

另外,我们再来聊聊性能问题。为了返回所有匹配的元素,Array.filter需要查找整个数组。可以想象一下,如果有上百个元素满足过滤条件,那么返回的数组就很大。

为了避免这样的情况,我建议使用Array.find。它仅仅返回第一个满足过滤条件的元素。而且,Array.find会在查找到第一个满足条件的元素后就结束执行,而不会查找整个数组。

'use strict';

const characters = [
{ id: 1, name: 'ironman' },
{ id: 2, name: 'black_widow' },
{ id: 3, name: 'captain_america' },
{ id: 4, name: 'captain_america' },
]; function getCharacter(name) {
return character => character.name === name;
} console.log(characters.filter(getCharacter('captain_america')));
// [
// { id: 3, name: 'captain_america' },
// { id: 4, name: 'captain_america' },
// ] console.log(characters.find(getCharacter('captain_america')));
// { id: 3, name: 'captain_america' }

3. 不要使用Array.find,使用Array.some

我承认我犯过很多次错误。后来,一个很要好的朋友让我去看看MDN的文档,说有更好的解决方案。这个情况和刚刚提到的Array.indexOf/Array.includes很像。

在前面的例子中,我们看到Array.find接受一个过滤函数,返回满足的元素。那么,如果我们要查找一个数组是否包含某个元素的时候,Array.find是否是最佳的方案呢?可能不是,因为它返回的是元素具体的值,而不是布尔值。

我推荐大家使用Array.some,它会返回布尔值。

'use strict';

const characters = [
{ id: 1, name: 'ironman', env: 'marvel' },
{ id: 2, name: 'black_widow', env: 'marvel' },
{ id: 3, name: 'wonder_woman', env: 'dc_comics' },
]; function hasCharacterFrom(env) {
return character => character.env === env;
} console.log(characters.find(hasCharacterFrom('marvel')));
// { id: 1, name: 'ironman', env: 'marvel' } console.log(characters.some(hasCharacterFrom('marvel')));
// true

4. 不要使用Array.map和Array.filter组合,使用Array.reduce

Array.reduce有点难以理解!但是,如果我们每次在同时使用Array.filter和Array.map的时候,你是否觉察到需要点东西,对不?

我的意思是:我们对整个数组循环了2遍。第一次是过滤返回一个新的数组,第二次通过map又构造一个新的数组。我们使用了两个数组方法,每一个方法都有各自的回调函数,而且Array.filter返回的数组以后再也不会用到。

为了避免低效率,我建议使用Array.reduce。同样的结果,更优雅的代码!请看下面的例子:

'use strict';

const characters = [
{ name: 'ironman', env: 'marvel' },
{ name: 'black_widow', env: 'marvel' },
{ name: 'wonder_woman', env: 'dc_comics' },
]; console.log(
characters
.filter(character => character.env === 'marvel')
.map(character => Object.assign({}, character, { alsoSeenIn: ['Avengers'] }))
);
// [
// { name: 'ironman', env: 'marvel', alsoSeenIn: ['Avengers'] },
// { name: 'black_widow', env: 'marvel', alsoSeenIn: ['Avengers'] }
// ] console.log(
characters
.reduce((acc, character) => {
return character.env === 'marvel'
? acc.concat(Object.assign({}, character, { alsoSeenIn: ['Avengers'] }))
: acc;
}, [])
)
// [
// { name: 'ironman', env: 'marvel', alsoSeenIn: ['Avengers'] },
// { name: 'black_widow', env: 'marvel', alsoSeenIn: ['Avengers'] }
// ]

备注

malgosiastp and David Piepgrass在评论中提到:在使用Array.find和Array.includes前请注意检查兼容性,因为最新的IE不支持。

关于Fundebug

Fundebug专注于JavaScript、微信小程序、微信小游戏、支付宝小程序、React Native、Node.js和Java实时BUG监控。 自从2016年双十一正式上线,Fundebug累计处理了6亿+错误事件,得到了Google、360、金山软件等众多知名用户的认可。欢迎免费试用!

版权声明:

转载时请注明作者Fundebug以及本文地址:

https://blog.fundebug.com/2018/09/06/make-better-use-of-arrays/

4个错误使用JavaScript数组方法的案例的更多相关文章

  1. JavaScript数组方法--every、some、fill

    接上一篇,JavaScript数组方法--concat.push,继续其他的数组方法. every:every() 方法测试数组的所有元素是否都通过了指定函数的测试. 先看其使用方法: functio ...

  2. 【译】你应该了解的JavaScript数组方法

    让我们来做一个大胆的声明:for循环通常是无用的,而且还导致代码难以理解.当涉及迭代数组.查找元素.或对其排序或者你想到的任何东西,都可能有一个你可以使用的数组方法. 然而,尽管这些方法很有用,但是其 ...

  3. JavaScript数组方法大全(推荐)

    原网址:http://www.jb51.net/article/87930.htm 数组在笔试中经常会出现的面试题,javascript中的数组与其他语言中的数组有些不同,为了方便之后数组的方法学习, ...

  4. JavaScript 数组方法处理字符串 prototype

    js中数组有许多方法,如join.map,reverse.字符串没有这些方法,可以“借用”数组的方法来处理字符串. <!doctype html> <html lang=" ...

  5. 2018.2.27 JavaScript数组方法应用

    JavaScript数组方法应用 1.找出元素item在给定数组arr中的位置 function indexOf(arr,item){ return arr.indexOf(item); } func ...

  6. JavaScript数组方法详解

    JavaScript数组方法详解 JavaScript中数组的方法种类众多,在ES3-ES7不同版本时期都有新方法:并且数组的方法还有原型方法和从object继承的方法,这里我们只介绍数组在每个版本中 ...

  7. JavaScript数组方法速查,32个数组的常用方法和属性

    JavaScript数组方法速查手册极简版 http://30ke.cn/doc/js-array-method JavaScript数组方法速查手册极简版中共收了32个数组的常用方法和属性,并根据方 ...

  8. JavaScript数组方法大集合

    JavaScript数组方法集合 本文总结一下js数组处理用到的所有的方法.自己做个笔记. 数组方法 concat() 合并两个或多个数组 concat()能合并两个或者多个数组,不会更改当前数组,而 ...

  9. 一站式超全JavaScript数组方法大全

    一站式JavaScript数组方法大全(建议收藏) 方法一览表 详细操作 本人总结了JavaScript中有关数组的几乎所有方法(包含ES6之后新增的),并逐一用代码进行演示使用,希望可以帮助大家! ...

随机推荐

  1. 做JAVA开发的同学一定遇到过的爆表问题,看这里解决

    欢迎大家前往腾讯云+社区,获取更多腾讯海量技术实践干货哦~ 本文由净地发表于云+社区专栏 记一次Java线上服务器CPU过载问题的排查过程,详解排查过程中用到的Java性能监测工具:jvisualvm ...

  2. hotmail 收不到邮件的问题

    之前用 hotmail 注册过一个 aws 账号,起了一个 ec2 的免费一年的 VPS,然后没怎么用,不久就把这事忘了. 直到有一天手机收到信用卡扣款消息,我就马上去登账号,却怎么也想不起密码来了, ...

  3. Android开发工程师文集-layout_weight讲解

    前言 大家好,给大家带来Android开发工程师文集-layout_weight讲解的概述,希望你们喜欢 Layout_weight的相关代码展示 <TextView android:layou ...

  4. java相关技术问答(二)

    String为什么是final的 首先是为了安全性,final表示不可变,不可被继承,不能修改其方法保证安全 在多线程环境下,final类型的String保证线程安全 String支持字符串常量池,相 ...

  5. IDEA快捷键整理

                                                                              IDEA快捷键整理 一.修改快捷键方法: 点击 Fi ...

  6. 关于如何使`(a === 1 && a === 2 && a === 3)`返回`true`问题的思考

    看见这个面试题目,第一反应就是在变量a取值时进行了一些改变,那就要用getter,关于存取器的介绍可以看这里 var temp = 1; Object.defineProperty(window, ' ...

  7. BonnMotion支持的几种移动模型

    BonnMotion是一款基于java的移动场景产生和分析工具,常用来研究mobile ad hoc network的特征.其产生的移动场景可以导入到几款网络模拟器中进行模拟分析,例如:NS2,NS3 ...

  8. python3模块: os

    简介 os模块主要用于提供系统高级别的操作. 常用方法 os.access(path, mode) # 检验权限模式 os.chdir(path) # 改变当前工作目录 os.chflags(path ...

  9. 阿里P9架构师讲解从单机至亿级流量大型网站系统架构的演进过程

    阶段一.单机构建网站 网站的初期,我们经常会在单机上跑我们所有的程序和软件.此时我们使用一个容器,如tomcat.jetty.jboos,然后直接使用JSP/servlet技术,或者使用一些开源的框架 ...

  10. Python日常实践(1)——SQL Prompt的Snippets批量整理

    引言 个人平时在写sql脚本的时候会使用到SQL Prompt这款插件,除了强大的智能提示和格式化sql语句功能,我还喜欢使用Snippets代码段功能.比如我们可以在查下分析器输入ssf后按Tab键 ...