JavaScript数组方法的错误使用例子


Posted in Javascript onSeptember 13, 2018

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'] }
// ]
Javascript 相关文章推荐
Javascript 判断 object 的特定类转载
Feb 01 Javascript
javascript入门·图片对象(无刷新变换图片)\滚动图像
Oct 01 Javascript
jQuery选择没有colspan属性的td的代码
Jul 06 Javascript
25个非常棒的jQuery滑块插件和教程小结
Sep 02 Javascript
JQuery性能优化的几点建议
May 14 Javascript
bootstrap table 服务器端分页例子分享
Feb 10 Javascript
通过实例理解javascript中没有函数重载的概念
Jun 03 Javascript
jquery文字填写自动高度的实现方法
Nov 07 Javascript
angular.js指令中transclude选项及ng-transclude指令详解
May 24 Javascript
Js面试算法详解
Apr 08 Javascript
JS实现前端路由功能示例【原生路由】
May 29 Javascript
解决vue项目input输入框双向绑定数据不实时生效问题
Aug 05 Javascript
vue仿element实现分页器效果
Sep 13 #Javascript
区别JavaScript函数声明与变量声明
Sep 12 #Javascript
详解js中Array的方法及技巧
Sep 12 #Javascript
Angularjs Ng_repeat中实现复选框选中并显示不同的样式方法
Sep 12 #Javascript
angularjs下ng-repeat点击元素改变样式的实现方法
Sep 12 #Javascript
angularjs的单选框+ng-repeat的实现方法
Sep 12 #Javascript
vue服务端渲染缓存应用详解
Sep 12 #Javascript
You might like
全国FM电台频率大全 - 25 云南省
2020/03/11 无线电
php实现MD5加密16位(不要默认的32位)
2013/08/12 PHP
解决CodeIgniter伪静态失效
2014/06/09 PHP
php快速排序原理与实现方法分析
2016/05/26 PHP
解决在laravel中leftjoin带条件查询没有返回右表为NULL的问题
2019/10/15 PHP
多个checkbox被选中时如何判断是否有自己想要的
2014/09/22 Javascript
jquery中append()与appendto()用法分析
2014/11/14 Javascript
JavaScript变量的作用域全解析
2015/08/14 Javascript
JS在一定时间内跳转页面及各种刷新页面的实现方法
2016/05/26 Javascript
微信小程序 本地存储及登录页面处理实例详解
2017/01/11 Javascript
jQuery简易时光轴实现方法示例
2017/03/13 Javascript
使用Xcache缓存器加速PHP网站的配置方法
2017/04/22 Javascript
es6在react中的应用代码解析
2017/11/08 Javascript
详解如何用babel转换es6的class语法
2018/04/03 Javascript
微信小程序实现多行文字滚动
2020/11/18 Javascript
微信小程序实现锚点跳转
2020/11/23 Javascript
[01:05:24]Ti4 冒泡赛第二天 iG vs NEWBEE 3
2014/07/15 DOTA
[59:00]OG vs TNC 2018国际邀请赛小组赛BO2 第一场 8.19
2018/08/21 DOTA
python实现百度关键词排名查询
2014/03/30 Python
Python实现SMTP发送邮件详细教程
2021/03/02 Python
浅谈django orm 优化
2018/08/18 Python
python实现操作文件(文件夹)
2019/10/31 Python
python爬虫容易学吗
2020/06/02 Python
多个版本的python共存时使用pip的正确做法
2020/10/26 Python
CSS3——齿轮转动关键代码
2013/05/02 HTML / CSS
html5 video标签屏蔽右键视频另存为的js代码
2013/11/12 HTML / CSS
10条PHP编程习惯
2014/05/26 面试题
C语言50道问题
2014/10/23 面试题
深圳茁壮笔试题
2015/05/28 面试题
个人查摆剖析材料
2014/02/04 职场文书
向国旗敬礼活动总结范文2014
2014/09/27 职场文书
给老婆的道歉信
2015/01/20 职场文书
销售员岗位职责
2015/02/10 职场文书
征求意见函
2015/06/05 职场文书
Nginx同一个域名配置多个项目的实现方法
2021/03/31 Servers
Python可视化神器pyecharts绘制水球图
2022/07/07 Python