JavaScript数组方法的错误使用例子

 更新时间:2018年09月13日 08:41:25   投稿:laozhang  
在本篇文章中我们给大家分享了几种使用JavaScript数组容易出错的例子,需要的朋友们可以参考下。

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'] }
// ]

相关文章

  • swiper4实现移动端导航切换

    swiper4实现移动端导航切换

    这篇文章主要为大家详细介绍了swiper4实现移动端导航切换,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2019-09-09
  • 微信小程序class封装http代码实例

    微信小程序class封装http代码实例

    这篇文章主要介绍了微信小程序class封装http,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2019-08-08
  • fullpage.js全屏滚动插件使用实例

    fullpage.js全屏滚动插件使用实例

    这篇文章主要介绍了fullpage.js全屏滚动插件使用,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2016-09-09
  • 基于JS简单实现手持弹幕功能+文字抖动特效代码

    基于JS简单实现手持弹幕功能+文字抖动特效代码

    这篇文章主要介绍了基于JS简单实现手持弹幕功能+文字抖动特效代码,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2021-03-03
  • javascript框架设计读书笔记之模块加载系统

    javascript框架设计读书笔记之模块加载系统

    本文是司徒正美的《javascript框架设计》的第二章模块加载系统的读书笔记,根据自己的理解,简要的跟大家讲述了本章的主要内容,方便大家更好的学习。
    2014-12-12
  • HTML5+Canvas调用手机拍照功能实现图片上传(下)

    HTML5+Canvas调用手机拍照功能实现图片上传(下)

    这篇文章主要为大家详细介绍了HTML5+Canvas调用手机拍照功能实现图片上传,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2017-04-04
  • 一文详解如何在前端使用JS进行分类汇总

    一文详解如何在前端使用JS进行分类汇总

    这篇文章主要给大家介绍了关于如何在前端使用JS进行分类汇总的相关资料,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,需要的朋友可以参考下
    2023-04-04
  • Bootstrap模态框插件使用详解

    Bootstrap模态框插件使用详解

    这篇文章主要为大家详细介绍了Bootstrap模态框插件的使用方法,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2017-05-05
  • JavaScript实现给数字添加千位分隔符

    JavaScript实现给数字添加千位分隔符

    这篇文章主要为大家详细介绍了JavaScript如何实现给数字添加千位分隔符,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下
    2023-11-11
  • JS面试题之forEach能否跳出循环详解

    JS面试题之forEach能否跳出循环详解

    js中经常会使用foreach这个方法来遍历数组,这篇文章主要给大家介绍了关于JS面试题之forEach能否跳出循环的相关资料,需要的朋友可以参考下
    2021-06-06

最新评论