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 相关文章推荐
js弹窗代码 可以指定弹出间隔
Jul 03 Javascript
js操作滚动条事件实例
Jan 29 Javascript
JavaScript实现强制重定向至HTTPS页面
Jun 10 Javascript
js仿腾讯QQ的web登陆界面
Aug 19 Javascript
JavaScript面向对象编写购物车功能
Aug 19 Javascript
原生JS实现几个常用DOM操作API实例
Jan 19 Javascript
vue中倒计时组件的实例代码
Jul 06 Javascript
Vue页面跳转动画效果的实现方法
Sep 23 Javascript
在Vant的基础上实现添加表单验证框架的方法示例
Dec 05 Javascript
小程序开发中如何使用async-await并封装公共异步请求的方法
Jan 20 Javascript
将RGB值转换为灰度值的简单算法
Oct 09 Javascript
用js限制网页只在微信浏览器中打开(或者只能手机端访问)
Dec 24 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
php5中date()得出的时间为什么不是当前时间的解决方法
2008/06/30 PHP
PHP 模拟登陆MSN并获得用户信息
2009/05/16 PHP
Cakephp 执行主要流程
2010/03/24 PHP
微信接口生成带参数的二维码
2017/07/31 PHP
php爬取天猫和淘宝商品数据
2018/02/23 PHP
jQuery学习笔记之DOM对象和jQuery对象
2010/12/22 Javascript
js实现touch移动触屏滑动事件
2015/04/17 Javascript
javascript实现删除前弹出确认框
2015/06/04 Javascript
JavaScript的React框架中的JSX语法学习入门教程
2016/03/05 Javascript
再谈Javascript中的基本类型和引用类型(推荐)
2016/07/01 Javascript
JavaScript中 ES6 generator数据类型详解
2016/08/11 Javascript
JavaScript实现鼠标点击导航栏变色特效
2017/02/08 Javascript
令按钮悬浮在(手机)页面底部的实现方法
2017/05/02 Javascript
基于jQuery Ajax实现下拉框无刷新联动
2017/12/06 jQuery
JavaScript实现左右滚动电影画布
2020/02/06 Javascript
Python发送email的3种方法
2015/04/28 Python
Python中基本的日期时间处理的学习教程
2015/10/16 Python
Python使用matplotlib绘制正弦和余弦曲线的方法示例
2018/01/06 Python
pyqt5简介及安装方法介绍
2018/01/31 Python
利用python实现微信头像加红色数字功能
2018/03/26 Python
Python实现将json文件中向量写入Excel的方法
2018/03/26 Python
利用arcgis的python读取要素的X,Y方法
2018/12/22 Python
pandas进行时间数据的转换和计算时间差并提取年月日
2019/07/06 Python
python下载卫星云图合成gif的方法示例
2020/02/18 Python
python简单实现9宫格图片实例
2020/09/03 Python
美国家居用品和厨具购物网站:DealsDot
2019/10/07 全球购物
介绍一下MD5加密算法
2016/11/12 面试题
2015年公司保安年终工作总结
2015/05/14 职场文书
2015年学校综合治理工作总结
2015/07/20 职场文书
初中毕业生感言
2015/07/31 职场文书
合作协议书格式范本
2016/03/21 职场文书
2019最新劳动仲裁申请书!
2019/07/08 职场文书
创业计划书之少年玩具店
2019/09/05 职场文书
Python opencv缺陷检测的实现及问题解决
2021/04/24 Python
Python 实现绘制子图及子图刻度的变换等问题
2021/05/31 Python
Java中生成微信小程序太阳码的实现方案
2022/06/01 Java/Android