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

相关推荐
drebander1 分钟前
ubuntu 安装 chrome 及 版本匹配的 chromedriver
前端·chrome
软件技术NINI11 分钟前
html知识点框架
前端·html
深情废杨杨14 分钟前
前端vue-插值表达式和v-html的区别
前端·javascript·vue.js
GHUIJS15 分钟前
【vue3】vue3.3新特性真香
前端·javascript·vue.js
众生回避20 分钟前
鸿蒙ms参考
前端·javascript·vue.js
洛千陨21 分钟前
Vue + element-ui实现动态表单项以及动态校验规则
前端·vue.js
笃励1 小时前
Angular面试题五
javascript·ecmascript·angular.js
GHUIJS1 小时前
【vue3】vue3.5
前端·javascript·vue.js
-seventy-1 小时前
对 JavaScript 原型的理解
javascript·原型
&白帝&2 小时前
uniapp中使用picker-view选择时间
前端·uni-app