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和Asp、Php等后端程序间传值编码统一
Apr 17 Javascript
Bookmarklet实现启动jQuery(模仿 云输入法)
Sep 15 Javascript
javascript对数组的常用操作代码 数组方法总汇
Jan 27 Javascript
javascript算法题 求任意一个1-9位不重复的N位数在该组合中的大小排列序号
Jul 21 Javascript
Node.js中child_process实现多进程
Feb 03 Javascript
Jquery中find与each方法用法实例
Feb 04 Javascript
JavaScript使用二分查找算法在数组中查找数据的方法
Apr 07 Javascript
JavaScript实现简单获取当前网页网址的方法
Nov 09 Javascript
BOM系列第二篇之定时器requestAnimationFrame
Aug 17 Javascript
js和jQuery以及easyui实现对下拉框的指定赋值方法
Jan 23 jQuery
jQuery实现的淡入淡出与滑入滑出效果示例
Apr 18 jQuery
vue项目中引入vue-datepicker插件的详解
May 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 图像尺寸调整代码
2010/05/26 PHP
php网页版聊天软件实现代码
2016/08/12 PHP
PHP面向对象五大原则之依赖倒置原则(DIP)详解
2018/04/08 PHP
php+Ajax无刷新验证用户名操作实例详解
2019/03/04 PHP
jquery获取URL中参数解决中文乱码问题的两种方法
2013/12/18 Javascript
代码获取历史上的今天发生的事
2014/04/11 Javascript
JavaScript类型系统之基本数据类型与包装类型
2016/01/06 Javascript
JQuery+EasyUI轻松实现步骤条效果
2016/02/22 Javascript
vue过渡和animate.css结合使用详解
2017/06/14 Javascript
jquery+css3实现熊猫tv导航代码分享
2018/02/12 jQuery
详解angular路由高亮之RouterLinkActive
2018/04/28 Javascript
Vue加载组件、动态加载组件的几种方式
2018/08/31 Javascript
微信小程序当前时间时段选择器插件使用方法详解
2018/12/28 Javascript
Node.js动手撸一个静态资源服务器的方法
2019/03/09 Javascript
JavaScript find()方法及返回数据实例
2020/04/30 Javascript
VUE中V-IF条件判断改变元素的样式操作
2020/08/09 Javascript
vue 在服务器端直接修改请求的接口地址
2020/12/19 Vue.js
利用python模拟实现POST请求提交图片的方法
2017/07/25 Python
Python编程实现使用线性回归预测数据
2017/12/07 Python
Python使用pyh生成HTML文档的方法示例
2018/03/10 Python
解决Python3 控制台输出InsecureRequestWarning问题
2019/07/15 Python
python使用socket 先读取长度,在读取报文内容示例
2019/09/26 Python
用 python 进行微信好友信息分析
2020/11/28 Python
使用numpngw和matplotlib生成png动画的示例代码
2021/01/24 Python
html5 worker 实例(一) 为什么测试不到效果
2013/06/24 HTML / CSS
html5中canvas图表实现柱状图的示例
2017/11/13 HTML / CSS
HTML5 weui使用笔记
2019/11/21 HTML / CSS
美国婴儿和儿童家具网上商店:ABaby.com
2018/07/02 全球购物
路德维希•贝克(LUDWIG BECK)中文官网:德国大型美妆百货
2020/09/19 全球购物
实习期自我鉴定
2013/10/11 职场文书
社会公德演讲稿
2014/05/20 职场文书
2015年八一建军节慰问信
2015/03/23 职场文书
学习十八大的感悟
2015/08/11 职场文书
小学三年级语文教学反思
2016/03/03 职场文书
北京大学中文系教授推荐的10本小说
2019/08/08 职场文书
MySQL聚簇索引和非聚簇索引的区别详情
2022/06/14 MySQL