JavaScript中Array方法你该知道的正确打开方法
前言
在过去的几个月,我发现我的拉取请求中存在四个完全相同的JavaScript错误。于是我写了这篇文章,总结了如何在JavaScript中正确使用地使用Array的方法!
Array对象为JavaScript内置对象,具有以下属性:
属性 | 描述 |
---|---|
constructor | 返回对创建此对象的数组函数的引用。 |
length | 返回数组中元素的个数 |
prototype | 向对象添加属性和方法。 |
用Array.includes代替Array.indexOf
“如果你要在数组中查找元素,请使用Array.indexOf”。我记得在学习JavaScript的时候,在教材中读到这样的一句话。毫无疑问,这句话是真的!
MDN文档写道,Array.indexOf将“返回第一次出现给定元素的索引”。因此,如果我们稍后要在代码中使用这个返回的索引,那么使用Array.indexOf找到索引就对了。
但是,如果我们只想知道数组是否包含某个值,该怎么办?这似乎是一个是与否的问题,或者说是一个布尔值问题。对于这种情况,我建议使用返回布尔值的Array.includes。
'usestrict'; constcharacters=[ '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找到数组中包含的唯一值。
我们来看看这个方法的性能。要返回与回调函数匹配的所有元素,Array.filter必须遍历整个数组。此外,我们假设有数百个元素可以满足回调参数,那么过滤后的数组会非常大。
为了避免这种情况,我建议使用Array.find。它需要一个像Array.filter一样的回调函数作为参数,并返回满足回调函数的第一个元素的值。此外,只要找到第一个满足回调函数的元素,Array.find就会停止,无需遍历整个数组。通过Array.find来查找元素,我们可以更好地理解我们的意图。
'usestrict'; constcharacters=[ {id:1,name:'ironman'}, {id:2,name:'black_widow'}, {id:3,name:'captain_america'}, {id:4,name:'captain_america'}, ]; functiongetCharacter(name){ returncharacter=>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表示我们只想知道某个元素是否存在,而不需要得到这个元素。
'usestrict'; constcharacters=[ {id:1,name:'ironman',env:'marvel'}, {id:2,name:'black_widow',env:'marvel'}, {id:3,name:'wonder_woman',env:'dc_comics'}, ]; functionhasCharacterFrom(env){ returncharacter=>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值的具体情况,我们将它添加到累加器中或保持累加器不变。
'usestrict'; constcharacters=[ {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)=>{ returncharacter.env==='marvel' ?acc.concat(Object.assign({},character,{alsoSeenIn:['Avengers']})) :acc; },[]) ) //[ //{name:'ironman',env:'marvel',alsoSeenIn:['Avengers']}, //{name:'black_widow',env:'marvel',alsoSeenIn:['Avengers']} //]
英文原文:
https://medium.freecodecamp.org/heres-how-you-can-make-better-use-of-javascript-arrays-3efd6395af3c
总结
以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对毛票票的支持。