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连接access数据库的方法
Nov 17 Javascript
Mootools 1.2教程 输入过滤第二部分(字符串)
Sep 15 Javascript
购物车选中得到价格实现示例
Jan 26 Javascript
jQuery简易图片放大特效示例代码
Jun 09 Javascript
jQuery实现在textarea指定位置插入字符或表情的方法
Mar 11 Javascript
高效的jquery数字滚动特效
Dec 17 Javascript
WordPress中利用AJAX技术进行评论提交的实现示例
Jan 12 Javascript
Laravel整合Bootstrap 4的完整方案(推荐)
Jan 25 Javascript
对layui初始化列表的CheckBox属性详解
Sep 13 Javascript
vue 解决computed修改data数据的问题
Nov 06 Javascript
Vue混入mixins滚动触底的方法
Nov 22 Javascript
简单了解JavaScript sort方法
Nov 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和mysql的简单的dao类实现crud操作功能
2014/01/27 PHP
ThinkPHP访问不存在的模块跳转到404页面的方法
2014/06/19 PHP
ThinkPHP权限认证Auth实例详解
2014/07/22 PHP
Laravel学习教程之View模块详解
2017/09/18 PHP
PHP PDOStatement::setFetchMode讲解
2019/02/03 PHP
PHP simplexml_load_file()函数讲解
2019/02/03 PHP
php ActiveMQ的安装与使用方法图文教程
2020/02/23 PHP
论坛特效代码收集(落伍转发-不错)
2006/12/02 Javascript
JavaScript性能陷阱小结(附实例说明)
2010/12/28 Javascript
js中Image对象以及对其预加载处理示例
2013/11/20 Javascript
Javascript四舍五入Math.round()与Math.pow()使用介绍
2013/12/27 Javascript
JS对象转换为Jquery对象示例
2014/01/26 Javascript
JS中字符串trim()使用示例
2015/05/26 Javascript
使用JS中的exec()方法构造正则表达式验证
2016/08/01 Javascript
angularjs中ng-attr的用法详解
2016/12/31 Javascript
angular-cli修改端口号【angular2】
2017/04/19 Javascript
node.js中实现kindEditor图片上传功能的方法教程
2017/04/26 Javascript
AngularJS实现controller控制器间共享数据的方法示例
2017/10/30 Javascript
后台使用freeMarker和前端使用vue的方法及遇到的问题
2019/06/13 Javascript
python DataFrame获取行数、列数、索引及第几行第几列的值方法
2018/04/08 Python
Flask-Mail用法实例分析
2018/07/21 Python
Django 路由控制的实现
2019/07/17 Python
python thrift 实现 单端口多服务的过程
2020/06/08 Python
电子商务专业在校生实习自我鉴定
2013/09/29 职场文书
应用化学专业本科生求职信
2013/09/29 职场文书
给海归自荐信的建议
2013/12/13 职场文书
校友会欢迎辞
2014/01/13 职场文书
优秀导游先进事迹材料
2014/01/25 职场文书
工程技术员岗位职责
2014/03/02 职场文书
小小商店教学反思
2014/04/27 职场文书
群众路线教育实践活动思想汇报(2014特荐篇)
2014/09/16 职场文书
2014年党员自我评价材料
2014/09/22 职场文书
中学教师教学工作总结
2015/08/13 职场文书
写作技巧:怎样写好一份优秀工作总结?
2019/08/14 职场文书
图解排序算法之希尔排序Java实现
2021/06/26 Java/Android
SpringBoot整合阿里云视频点播的过程详解
2021/12/06 Java/Android