你用过这些JavaScript技巧和实践吗

本文翻译自 I Bet You Don't Use These JavaScript Tricks and Practices,作者:Nirjal Paudel, 略有删改。

本文推荐一些实际开发中的JavaScript技巧和实践,希望能对你有所帮助,有兴趣的可以看看原文。

1.使用FlatMap

JavaScript中的Flat Map是一个很好用的方法。Flat Map实质上是将映射技术和过滤数组技术结合在了一起。更建议你使用flatMap()而不是filter()map()的组合。

FlatMap只执行一次,不会生成中间数组,但是filter()map()的组合会生成一个中间数组。

js 复制代码
// using filterAndMap
console.time("filterAndMap")
const numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];

const squaredOddNumbers = numbers
    .filter(num => num % 2 !== 0)
    .map(num => num * num)

console.log(squaredOddNumbers); // [1, 9, 25, 49, 81]
console.timeEnd("filterAndMap")

以下是打印代码运行的执行时间:

js 复制代码
console.time("filterAndMap")
const numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];

const squaredOddNumbers = numbers.flatMap(num => 
    num % 2 !== 0 ? [num * num] : []
);


console.log(squaredOddNumbers); // [1, 9, 25, 49, 81]
console.timeEnd("filterAndMap")

以下是打印代码运行的执行时间:

通过两者运行的时间即可很容易的看出差距。

2. 数组排序

数组方法是一些帮助我们与数组进行交互的最重要的方法之一。在 JavaScript 中有许多数组方法可用。最常用的数组方法包括 .filter().find().map().reduce()。它们可以组合在一起产生一些很不错的效果,例如以下代码:

js 复制代码
const numbers = [9, 3, 6, 4, 8, 1, 2, 5, 7];

numbers
  .sort((a, b) => a - b)
  .filter((n) => n % 2 !== 0)
  .map((n) => n ** 3);

程序上面看起来不错,对吧?但是有一个问题。注意我们先对数字进行了排序,然后再应用过滤器。如果我们先应用过滤器,然后排序,最后再求幂,就可以执行更少的操作。这样我们可以优化一组由点运算符连接的数组方法。

上面的最佳代码是:

js 复制代码
const numbers = [9, 3, 6, 4, 8, 1, 2, 5, 7];

numbers
  .filter((n) => n % 2 !== 0)
  .sort((a, b) => a - b)
  .map((n) => n ** 3);

3.不经常使用的 reduce 函数

我见过很多前端开发者在处理这个问题时遇到困难。比如像react-charts这样的包要求以对象结构传递数据,但实际上react-charts的实现要求以键分组的格式传递数据,所以我见过大多数开发者使用.forEach()方法或错误地使用map()方法来处理这个问题,就像下面这样:

js 复制代码
fetch("https://jsonplaceholder.typicode.com/todos/")
  .then(res=>res.json())
  .then(todos=>{
    
    // using Map
    const todosForUserMap = {};
    todos.forEach(todo=>{
      if (todosForUserMap[todo.userId]){
        todosForUserMap[todo.userId].push(todo);  
      }else{
        todosForUserMap[todo.userId] = [todo];
      }  
    })

    console.log(todosForUserMap)
  })

这种方法很好,它使用了forEach方法而不是map方法。map方法在这里明显不适用,因为它会在幕后会为每个元素创建一个数组。假设数组有1000个条目,那么在map中将创建一个1000个条目的空数组,而在forEach中不会创建这样的数组。

但我们不使用上面的两种方法,一个相当简洁和易读的方法是使用数组的 reduce 方法。优化后的代码如下:

js 复制代码
fetch("https://jsonplaceholder.typicode.com/todos/")
  .then(res=>res.json())
  .then(todos=>{
    
    // using Map
    const todosForUserMap = todos.reduce((accumulator, todo)=>{
      if (accumulator[todo.userId]) accumulator[todo.userId].push(todo);
      if (!accumulator[todo.userId]) accumulator[todo.userId] = [todo];
      return accumulator;
    },{})

    console.log(todosForUserMap)
  })

这样不会创建任何不必要的数组,代码更干净且更好用。它与forEach()类似,但建议用下面的方式,因为它更清晰,更容易理解。

4.未充分使用原生JavaScript类

JavaScript自带很多原生javascript类,可以帮助你很容易地创建/实例化URL,Header等。以下代码可能比较常见,有人会试图像这样在URL中处理参数。

js 复制代码
async function getUrl(userId, limit, category){
  return `https://fakestoreapi.com/products${category ? `/category/${category}` : ""}${limit ? Number(limit):""}${userId? Number(userId):""}`;    
}

上面的代码看着很混乱,很可能会中断,每次都需要你在最后添加一些规则,添加一些其他参数,通过使用本地类,如URL,我们可以改进更好的代码。改进的代码看起来像下面这样。

js 复制代码
function constructURL(category, limit, userId) {
  const baseURL = "https://fakestoreapi.com/products";
  const url = new URL(baseURL);
  const params = new URLSearchParams();

  if (category) url.pathname += `/category/${category}`;
  if (limit) params.append('limit', Number(limit).toString());
  if (userId) params.append('userId', Number(userId).toString());

  url.search = params.toString();
  return url.toString();
}

这样就可以在同一个文件中处理复杂的URL构建条件。这里的URL对象遵循建造者模式(BuilderPattern),它是你可以在代码中实现的许多设计模式之一,可以将复杂的逻辑放在一个单独的地方处理,同时也提高了代码可读性。

最后

这些JavaScript技巧和实践旨在提高开发效率、增强代码质量和性能优化。希望对你有用且能从中获得一些启发,并应用到实际项目中。


看完本文如果觉得有用,记得点个赞支持,收藏起来说不定哪天就用上啦~

专注前端开发,分享前端相关技术干货,公众号:南城大前端(ID: nanchengfe)

相关推荐
转角羊儿8 分钟前
uni-app文章列表制作⑧
前端·javascript·uni-app
大G哥14 分钟前
python 数据类型----可变数据类型
linux·服务器·开发语言·前端·python
hong_zc38 分钟前
初始 html
前端·html
小小吱43 分钟前
HTML动画
前端·html
Bio Coder1 小时前
学习用 Javascript、HTML、CSS 以及 Node.js 开发一个 uTools 插件,学习计划及其周期
javascript·学习·html·开发·utools
糊涂涂是个小盆友1 小时前
前端 - 使用uniapp+vue搭建前端项目(app端)
前端·vue.js·uni-app
浮华似水1 小时前
Javascirpt时区——脱坑指南
前端
王二端茶倒水2 小时前
大龄程序员兼职跑外卖第五周之亲身感悟
前端·后端·程序员
_oP_i2 小时前
Web 与 Unity 之间的交互
前端·unity·交互
钢铁小狗侠2 小时前
前端(1)——快速入门HTML
前端·html