你用过这些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)

相关推荐
哀木6 小时前
一个简单的套壳方案,就能让你的 Agent 少做重复初始化
前端
问心无愧05136 小时前
ctf show web入门27
前端
小村儿6 小时前
给 AI Agent 装上"长期记忆":Karpathy 的 LLM Wiki 思想,我做成了工具
前端·后端·ai编程
竹林8186 小时前
用ethers.js连接MetaMask实现Web3钱包登录:从踩坑到稳定运行的完整记录
前端·javascript
heyCHEEMS6 小时前
如何用 Recast 实现静态配置文件源码级读写
前端·node.js
心连欣6 小时前
从零开始,学习所有指令!
前端·javascript·vue.js
review445436 小时前
大模型和function calling分别是如何工作的
前端
东东同学6 小时前
耗时一个月,我把 Nuxt 首屏性能排障经验做成了一个 AI Skill
前端·agent
冴羽7 小时前
超越 Vibe Coding —— AI 辅助编程指南
前端·ai编程·vibecoding
梦想的颜色7 小时前
一天一个SKILL——前端最佳自动化测试 webapp-testing
前端·web app