JS+TSWeb 前端开发 学校

是时候换个姿势使用 JavaScript 数组了

2019-11-25  本文已影响0人  1024译站
Photo by Ben White on Unsplash

随着 ECMASCRIPT 6/7/8 的推进,越来越多的 JavaScript 新特性被主流浏览器支持。长期以来广大 JS 开发者习以为常的用法,也该考虑换换姿势了。今天就来聊聊数组的新用法,相信从此以后你的代码会清爽很多。

1. 用 Array.includes 替代 Array.indexOf

差不多从学会 JavaScript 开始,我们都是这样判断数组是否包含某个元素的:Array.indexOf(element) > -1。且不说语义上不够直观,在条件判断语句中经常会忘记加上>-1 从而导致 bug。试试Array新增的includes方法,它直接返回truefalse表示数组是否包含元素。这样是不是直观多了?

'use strict';

const characters = [
  '钢铁侠',
  '黑寡妇',
  '浩克',
  '美国队长',
  '浩克',
  '雷神',
];

console.log(characters.indexOf('浩克'));
// 2
console.log(characters.indexOf('蝙蝠侠'));
// -1

console.log(characters.includes('浩克'));
// true
console.log(characters.includes('蝙蝠侠'));
// false

2. 用 Array.find 替代 Array.filter

同样,为了在对象数组中查找符合条件的对象,以前的做法是用filter筛选,它会返回符合条件的数组。但我们的目的是查找具体的单个对象,所以使用find更合适:

'use strict';

const characters = [
  { id: 1, name: '钢铁侠' },
  { id: 2, name: '黑寡妇' },
  { id: 3, name: '美国队长' },
  { id: 4, name: '美国队长' },
];

function getCharacter(name) {
  return character => character.name === name;
}

console.log(characters.filter(getCharacter('美国队长')));
// [
//   { id: 3, name: '美国队长' },
//   { id: 4, name: '美国队长' },
// ]

console.log(characters.find(getCharacter('美国队长')));
// { id: 3, name: '美国队长' }

3. 用 Array.some 替代 Array.find

有时候我们需要判断对象数组中符合条件的对象是否存在,虽然用find也可以达到目的,但还是不够直接,最好能直接返回truefalseArray.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.reduce 替代 Array.filter 和 Array.map

Array.reduce这货看上去不那么好理解,但熟悉之后你会发现它非常好用。它实际上是一个叠加器,它遍历整个数组,把每个元素传入累加器函数执行一次,并把执行结果作为下一次迭代的输入参数。你可以在叠加器里做任何事,比如数字求和、数组和字符串拼接、对象属性操作等。

比如这样一个需求,在城市数组里筛选属于广东省的,然后给每个对象加上一个地区属性。以往的做法是先用filter筛选出结果数组,再用map构造新的对象数组。这样其实遍历了两次数组,性能不够好。使用Array.reduce可以实现一次遍历就完成了:

'use strict';

const cities= [
  { city: '广州市', province: '广东省' },
  { city: '深圳市', province: '广东省' },
  { city: '石家庄市', province: '河北省' },
];

console.log(
  cities
    .filter(city=> city.province=== '广东省')
    .map(city=> Object.assign({}, city, { region: '华南区' }))
);
// [
//   { city: '广州市', province: '广东省', region: '华南区' },
//   { city: '深圳市', province: '广东省', region: '华南区' }
// ]

console.log(
  cities
    .reduce((acc, city) => {
      return city.province=== '广东省'
        ? acc.concat(Object.assign({}, city, { region: '华南区' }))
        : acc;
    }, [])
)
// [
//   { city: '广州市', province: '广东省', region: '华南区' },
//   { city: '深圳市', province: '广东省', region: '华南区' }
// ]

总结

新的语言标准通常会提供更加便捷和高性能的操作来实现某项功能。虽然也可以通过旧的 API 绕弯子实现,但无论从可读性还是性能上来说,简单直接的 API 无疑更受欢迎。

如果你觉得文章有用,可以关注我的微信公众号:1024译站,下一篇更精彩!


微信公众号:1024译站
上一篇下一篇

猜你喜欢

热点阅读