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 相关文章推荐
ASP.NET jQuery 实例16 通过控件CustomValidator验证RadioButtonList
Feb 03 Javascript
JqueryMobile动态生成listView并实现刷新的两种方法
Mar 05 Javascript
jquery原理以及学习技巧介绍
Nov 11 Javascript
JavaScript File API实现文件上传预览
Feb 02 Javascript
jQuery mobile的header和footer在点击屏幕的时候消失的解决办法
Jul 01 Javascript
JavaScript中关于iframe滚动条的去除和保留
Nov 17 Javascript
JavaScript中数据类型转换总结
Dec 25 Javascript
jQuery remove()过滤被删除的元素(推荐)
Jul 18 jQuery
Vue实现搜索 和新闻列表功能简单范例
Mar 16 Javascript
js实现全选反选不选功能代码详解
Apr 24 Javascript
你不可不知的Vue.js列表渲染详解
Oct 01 Javascript
layui清除radio的选中状态实例
Nov 14 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
PHP 和 MySQL 基础教程(一)
2006/10/09 PHP
使用php 获取时间今天明天昨天时间戳的详解
2013/06/20 PHP
PHP中实现Bloom Filter算法
2015/03/30 PHP
详解WordPress中分类函数wp_list_categories的使用
2016/01/04 PHP
Jquery下的26个实用小技巧(jQuery tips, tricks & solutions)
2010/03/01 Javascript
JS继承用法实例分析
2015/02/05 Javascript
浅谈JavaScript数据类型
2015/03/03 Javascript
jQuery Mobile 触摸事件实例
2016/06/04 Javascript
js简单实现调整网页字体大小的方法
2016/07/23 Javascript
简单快速的实现js计算器功能
2017/08/17 Javascript
微信小程序使用image组件显示图片的方法【附源码下载】
2017/12/08 Javascript
vue 之 css module的使用方法
2018/12/04 Javascript
JavaScript常用工具方法封装
2019/02/12 Javascript
详解JavaScript之Array.reduce源码解读
2020/11/01 Javascript
[01:20:06]TNC vs VG 2018国际邀请赛小组赛BO2 第二场 8.16
2018/08/17 DOTA
Python调用命令行进度条的方法
2015/05/05 Python
python数字图像处理之高级滤波代码详解
2017/11/23 Python
Python字符串hashlib加密模块使用案例
2020/03/10 Python
python中函数返回多个结果的实例方法
2020/12/16 Python
Python LMDB库的使用示例
2021/02/14 Python
css3 自定义字体font-face使用介绍
2014/05/14 HTML / CSS
巧用 CSS3的webkit-box-reflect 倒影实现各类动效
2021/03/05 HTML / CSS
公务员职务工作的自我评价
2013/11/01 职场文书
优秀学生事迹材料
2014/02/08 职场文书
优秀员工推荐信
2014/05/10 职场文书
技校毕业生自荐信
2014/06/03 职场文书
2014年档案管理员工作总结
2014/12/01 职场文书
初中生考试作弊检讨书
2014/12/14 职场文书
内乡县衙导游词
2015/02/05 职场文书
生产现场禁烟通知
2015/04/23 职场文书
交通肇事罪辩护词
2015/05/21 职场文书
标准版个人借条怎么写?以及什么是借条?
2019/08/28 职场文书
虚拟机linux端mysql数据库无法远程访问的解决办法
2021/05/26 MySQL
详解thinkphp的Auth类认证
2021/05/28 PHP
PostGIS的安装与入门使用指南
2022/01/18 PostgreSQL
基于Apache Hudi在Google云构建数据湖平台的思路详解
2022/04/07 Servers