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 相关文章推荐
jquery 学习之二 属性 文本与值(text,val)
Nov 25 Javascript
在firefox和Chrome下关闭浏览器窗口无效的解决方法
Jan 16 Javascript
jquery中each方法示例和常用选择器
Jul 08 Javascript
node.js中的fs.ftruncate方法使用说明
Dec 15 Javascript
PHP中CURL的几个经典应用实例
Jan 23 Javascript
程序员必知35个jQuery 代码片段
Nov 05 Javascript
微信小程序 http请求详细介绍
Oct 09 Javascript
详解Vue文档中几个易忽视部分的剖析
Mar 24 Javascript
Node.js使用Angular简单示例
May 11 Javascript
详解javascript appendChild()的完整功能
Aug 18 Javascript
vue点击当前路由高亮小案例
Sep 26 Javascript
js 动态校验开始结束时间的实现代码
May 25 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 数据库树的遍历方法
2009/02/06 PHP
apache+php完美解决301重定向的两种方法
2011/06/08 PHP
php操作MongoDB类实例
2015/06/17 PHP
Zend Framework框架之Zend_Mail实现发送Email邮件验证功能及解决标题乱码的方法
2016/03/21 PHP
php使用自定义函数实现汉字分割替换功能示例
2017/01/30 PHP
PHP基于DOM创建xml文档的方法示例
2017/02/08 PHP
解决tp5在nginx下修改配置访问的问题
2019/10/16 PHP
php设计模式之模板模式实例分析【星际争霸游戏案例】
2020/03/24 PHP
js作用域及作用域链概念理解及使用
2013/04/15 Javascript
Ext JS 4实现带week(星期)的日期选择控件(实战二)
2013/08/21 Javascript
javascript垃圾收集机制与内存泄漏详细解析
2013/11/11 Javascript
jQuery实现html table行Tr的复制、删除、计算功能
2017/07/10 jQuery
详细分析jsonp的原理和实现方式
2017/11/20 Javascript
bootstrap表格内容过长时用省略号表示的解决方法
2017/11/21 Javascript
浅谈Angular 中何时取消订阅
2017/11/22 Javascript
实现单层json按照key字母顺序排序的示例
2017/12/06 Javascript
vue刷新和tab切换实例
2018/02/11 Javascript
详解用vue2.x版本+adminLTE开源框架搭建后台应用模版
2019/03/15 Javascript
Vue项目实现简单的权限控制管理功能
2019/07/17 Javascript
解决vue.js提交数组时出现数组下标的问题
2019/11/05 Javascript
Angular value与ngValue区别详解
2019/11/27 Javascript
[07:39]第一届亚洲邀请赛回顾视频
2017/02/14 DOTA
[42:32]完美世界DOTA2联赛循环赛 Magma vs PXG BO2第二场 10.28
2020/10/28 DOTA
Python运行的17个时新手常见错误小结
2012/08/07 Python
python socket网络编程之粘包问题详解
2018/04/28 Python
matplotlib实现热成像图colorbar和极坐标图的方法
2018/12/13 Python
Python使用matplotlib绘制圆形代码实例
2020/05/27 Python
CSS3圆角和渐变2种常用功能详解
2016/01/06 HTML / CSS
详解android与HTML混合开发总结
2018/06/06 HTML / CSS
怎样让char类型的东西转换成int类型
2013/12/09 面试题
班组长的岗位职责
2013/12/09 职场文书
《颐和园》教学反思
2014/02/26 职场文书
弘扬雷锋精神活动演讲稿
2014/03/04 职场文书
商务英语广告词大全
2014/03/18 职场文书
员工激励培训演讲稿
2014/09/16 职场文书
php 解析非标准json、非规范json
2021/04/01 PHP