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 数组克隆方法 小结
Mar 20 Javascript
在页面加载完成后通过jquery给多个span赋值
May 21 Javascript
关于javaScript注册click事件传递参数的不成功问题
Jul 18 Javascript
jQuery实现设置、移除文本框默认值功能
Jan 13 Javascript
javascript中innerText和innerHTML属性用法实例分析
May 13 Javascript
基于jquery实现放大镜效果
Aug 17 Javascript
jquery计算出left和top,让一个div水平垂直居中的简单实例
Jul 13 Javascript
js编写三级联动简单案例
Dec 21 Javascript
强大的 Angular 表单验证功能详细介绍
May 23 Javascript
addeventlistener监听scroll跟touch(实例讲解)
Aug 04 Javascript
微信小程序支付之c#后台实现方法
Oct 19 Javascript
解决vue页面刷新,数据丢失的问题
Nov 24 Vue.js
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/08/19 PHP
PHP使用正则表达式清除超链接文本
2013/11/12 PHP
PHP中把错误日志保存在系统日志中(Windows系统)
2015/06/23 PHP
ubuntu下配置nginx+php+mysql详解
2015/09/10 PHP
Thinkphp框架开发移动端接口(1)
2016/08/18 PHP
Ubuntu VPS中wordpress网站打开时提示”建立数据库连接错误”的解决办法
2016/11/03 PHP
PHP编程实现的TCP服务端和客户端功能示例
2018/04/13 PHP
jquery插件珍藏(图片局部放大/信息提示框)
2013/01/08 Javascript
使用jquery实现仿百度自动补全特效
2015/07/23 Javascript
纯javaScript、jQuery实现个性化图片轮播【推荐】
2017/01/08 Javascript
Vue文件配置全局变量的实例
2018/09/06 Javascript
vue富文本编辑器组件vue-quill-edit使用教程
2018/09/21 Javascript
基于Vue插入视频的2种方法小结
2019/04/02 Javascript
vue自定义表单生成器form-create使用详解
2019/07/19 Javascript
jquery简易手风琴插件的封装
2020/10/13 jQuery
python关闭windows进程的方法
2015/04/18 Python
python利用正则表达式提取字符串
2016/12/08 Python
python实现微信小程序自动回复
2018/09/10 Python
Python 实现异步调用函数的示例讲解
2018/10/14 Python
在PYQT5中QscrollArea(滚动条)的使用方法
2019/06/14 Python
对python3中的RE(正则表达式)-详细总结
2019/07/23 Python
利用Python校准本地时间的方法教程
2019/10/31 Python
使用pytorch搭建AlexNet操作(微调预训练模型及手动搭建)
2020/01/18 Python
土耳其家居建材网站:Koçtaş
2016/11/22 全球购物
纽约著名的服装辅料来源:M&J Trimming
2017/07/26 全球购物
Rodd & Gunn澳大利亚官网:新西兰男装品牌
2018/09/25 全球购物
沙特阿拉伯家用电器和电子产品购物网站:Sheta and Saif
2020/04/03 全球购物
实习教师个人的自我评价
2013/11/08 职场文书
读书伴我成长演讲稿
2014/05/07 职场文书
小区的门卫岗位职责
2014/10/01 职场文书
辞职信模板(中英文版)
2015/02/27 职场文书
幼师辞职信范文
2015/02/27 职场文书
《自己去吧》教学反思
2016/02/16 职场文书
公开致歉信
2019/06/24 职场文书
神州牡丹园的导游词
2019/11/20 职场文书
python文件与路径操作神器 pathlib
2022/04/01 Python