JavaScript中Array的正确使用方式

在 JavaScript 中正确使用地使用 Array 的方法以下:数组

用 Array.includes 代替 Array.indexOf函数

“若是你要在数组中查找元素,请使用 Array.indexOf”。性能

MDN 文档写道,Array.indexOf 将“返回第一次出现给定元素的索引”。所以,若是咱们稍后要在代码中使用这个返回的索引,那么使用 Array.indexOf 找到索引就对了。spa

可是,若是咱们只想知道数组是否包含某个值,该怎么办?这彷佛是一个是与否的问题,或者说是一个布尔值问题。对于这种状况,建议使用返回布尔值的 Array.includes。code

'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  
使用 Array.find 而不是 Array.filter 

Array.filter 是一个很是有用的方法。它接受一个回调函数做为参数,基于一个包含全部元素的数组建立出一个新的数组。正如它的名字同样,咱们使用这个方法来过滤元素,得到更短的数组。对象

可是,若是回调函数只能返回一个元素,那么我就不推荐使用这个方法,例如使用回调函数来过滤惟一 ID。在这种状况下,Array.filter 将返回一个只包含一个元素的新数组。咱们的意图多是经过查找特定的 ID 找到数组中包含的惟一值。blog

咱们来看看这个方法的性能。要返回与回调函数匹配的全部元素,Array.filter 必须遍历整个数组。此外,咱们假设有数百个元素能够知足回调参数,那么过滤后的数组会很是大。索引

为了不这种状况,建议使用 Array.find。它须要一个像 Array.filter 同样的回调函数做为参数,并返回知足回调函数的第一个元素的值。此外,只要找到第一个知足回调函数的元素,Array.find 就会中止,无需遍历整个数组。经过 Array.find 来查找元素,咱们能够更好地理解咱们的意图。ip

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

用 Array.some 代替 Array.find文档

我认可这个错误我犯了不少次。而后,一位善良的朋友告诉我,最好能够先参考 MDN 文档。这与上面的 Array.indexOf/Array.includes 很是类似。

在前面的例子中,咱们看到 Array.find 须要一个回调函数做为参数,并返回一个元素。若是咱们想要知道数组是否包含某个值,Array.find 是最好的解决方案吗?可能不是,由于它返回的是一个元素值,而不是一个布尔值。

对于这种状况,建议使用 Array.some,它返回所需的布尔值。另外,从语义上看,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 

使用 Array.reduce 而不是连接 Array.filter 和 Array.map

Array.reduce 不容易理解。事实确实如此!可是,若是咱们使用 Array.filter 和 Array.map 的组合,总感受缺乏了什么,咱们遍历了两次数组。第一次过滤数组并建立一个较短的数组,第二次又基于 Array.filter 得到数组建立一个包含新值的数组。为了得到咱们想要的新数组,咱们使用了两个 Array 方法。每一个方法都有本身的回调函数和一个用不到的数组——由 Array.filter 建立的那个数组。

为了不这种性能损耗,建议是使用 Array.reduce。结果是同样的,代码却更简单! 咱们可使用 Array.reduce 进行过滤,并将目标元素添加到累加器中。累加器能够是递增的数字、要填充的对象、要链接的字符串或数组。

在咱们的例子中,由于以前使用了 Array.map,因此我建议使用 Array.reduce 将知足条件的数组元素加入到累加器中。在下面的示例中,根据 env 值的具体状况,咱们将它添加到累加器中或保持累加器不变。

'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'] }  // ] 
相关文章
相关标签/搜索