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 相关文章推荐
wordpress之js库集合研究介绍
Aug 17 Javascript
Ajax执行顺序流程及回调问题分析
Dec 10 Javascript
jQuery如何获取同一个类标签的所有值(默认无法获取)
Sep 25 Javascript
javascript中的Base64、UTF8编码与解码详解
Mar 18 Javascript
JS实现的5级联动Select下拉选择框实例
Aug 17 Javascript
JavaScript 判断一个对象{}是否为空对象的简单方法
Oct 09 Javascript
关于Vue.js 2.0的Vuex 2.0 你需要更新的知识库
Nov 30 Javascript
Thinkphp5微信小程序获取用户信息接口的实例详解
Sep 26 Javascript
Angular2开发环境搭建教程之VS Code
Dec 15 Javascript
javascript实现获取一个日期段内每天不同的价格(计算入住总价格)
Feb 05 Javascript
VUE中使用MUI方法
Feb 12 Javascript
js实现移动端轮播图滑动切换
Dec 21 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关联数组的10个操作技巧
2013/01/21 PHP
PHP 如何获取二维数组中某个key的集合
2014/06/03 PHP
PHP读取txt文本文件并分页显示的方法
2015/03/11 PHP
php防止用户重复提交表单
2015/11/02 PHP
详谈php静态方法及普通方法的区别
2016/10/04 PHP
Yii框架日志记录Logging操作示例
2018/07/12 PHP
用js实现键盘方向键翻页功能的代码
2007/06/03 Javascript
JS实现的一个简单的Autocomplete自动完成例子
2014/04/16 Javascript
JavaScript中的闭包(Closure)详细介绍
2014/12/30 Javascript
在JavaScript中用getMinutes()方法返回指定的分时刻
2015/06/10 Javascript
基于JavaScript制作霓虹灯文字 代码 特效
2015/09/01 Javascript
JavaScript 经典实例日常收集整理(常用经典)
2016/03/30 Javascript
D3.js进阶系列之CSV表格文件的读取详解
2017/06/06 Javascript
vue mint-ui学习笔记之picker的使用
2017/10/11 Javascript
vue动态绑定组件子父组件多表单验证功能的实现代码
2018/05/14 Javascript
vue 实现数字滚动增加效果的实例代码
2018/07/06 Javascript
微信小程序实现下拉菜单切换效果
2020/03/30 Javascript
详解在Node.js中发起HTTP请求的5种方法
2019/01/10 Javascript
JS常见面试试题总结【去重、遍历、闭包、继承等】
2019/08/27 Javascript
原生JavaScript创建不可变对象的方法简单示例
2020/05/07 Javascript
python写的一个squid访问日志分析的小程序
2014/09/17 Python
对Python中type打开文件的方式介绍
2018/04/28 Python
在Pycharm中使用GitHub的方法步骤
2019/06/13 Python
Pandas中resample方法详解
2019/07/02 Python
Windows下PyCharm2018.3.2 安装教程(图文详解)
2019/10/24 Python
Python configparser模块常用方法解析
2020/05/22 Python
为什么需要版本控制
2016/10/28 面试题
前处理组长岗位职责
2014/03/01 职场文书
投资意向书范本
2014/04/01 职场文书
责任胜于能力演讲稿
2014/05/20 职场文书
工商管理本科生求职信
2014/07/13 职场文书
收银员岗位职责范本
2015/04/07 职场文书
2015年纪委工作总结
2015/05/13 职场文书
房产电话营销开场白
2015/05/29 职场文书
肖申克的救赎观后感
2015/06/02 职场文书
vue特效之翻牌动画
2022/04/20 Vue.js