前端领域的闭包入门及实战

211 阅读3分钟

前端领域的闭包入门和实战

1、闭包概念:

闭包是指在函数内部创建的一个函数,它可以访问到该函数的变量和参数,即使该函数已经返回并且调用它的上下文已经销毁,该闭包仍然可以使用这些变量和参数。

2、实战案例

  • 缓存数据

场景1:假设有一个函数 cacheData,它接受一个参数 url 并返回一个数据对象。我们可以使用闭包来缓存这些数据对象,以避免重复计算

function cacheData(url) {  
  const result = {};  
  function fetchData() {  
    if (result.data) {  
      return result.data;  
    }  
    result.data = await fetch(url);  
    return result.data;  
  }  
  return fetchData();  
}

在这个例子中,fetchData 函数是一个闭包,它内部的 if 语句检查 result 对象是否已经存在,如果是,就返回该对象。否则,它创建一个新的数据对象,并将该对象存储在 result 对象中。最后,fetchData 返回该对象,以便后续调用者可以访问该对象。

  • 实现高阶函数

场景2: 高阶函数通常使用闭包来实现。高阶函数允许函数作为参数传递给其他函数,从而实现函数的嵌套和递归。例如,我们可以使用闭包来实现一个高阶函数 map:

function map(arr, mapper) {  
  const result = [];  
  for (let i = 0; i < arr.length; i++) {  
    result.push(mapper(arr[i]));  
  }  
  return result;  
}

const array = [1, 2, 3, 4, 5];  
const result = map(array, num => num + 1);  
console.log(result); // [2, 3, 4, 5, 6]  

在这个例子中,map 函数接受两个参数,一个数组 arr 和一个函数 mapper。函数 mapper 将被传递给数组中的每个元素,并返回一个新的数组。map 函数将返回一个新的数组,该数组包含函数 mapper 返回的结果。

  • 实现模块化编程

在 JavaScript 中,可以使用闭包来实现模块化编程。例如,我们可以使用闭包在模块内部创建私有变量和函数,从而避免外部访问和修改这些变量和函数。例如,我们可以使用闭包来实现一个简单的模块化编程框架:

const api = {};

api.fetchData = async (url) => {  
  const data = await fetch(url);  
  return data.json();  
};

api.register = function (name, handler) {  
  const registerHandler = (url) => {  
    return api.fetchData(url).then(data => {  
      const dataHandler = { handle: handler };  
      return dataHandler[name];  
    });  
  };

  return registerHandler(url);  
};

const app = {  
  api,  
};

export default app;  

在这个例子中,api 对象是一个闭包,它内部的 fetchData 函数是一个闭包,它内部的 await 语句检查 data 对象是否已经存在。如果已经存在,就返回该对象。否则,它创建一个新的数据对象,并将该对象存储在 data 对象中。最后,api 返回一个函数,该函数接受一个 URL 参数,并返回一个 Promise 对象。该 Promise 对象将返回一个数据对象,该对象包含与 URL 相关的数据。

  • 实现事件循环

在 JavaScript 中,可以使用闭包来实现事件循环。事件循环用于处理用户输入和浏览器事件,通常使用一个闭包来维护事件处理程序的顺序执行。

  • 实现私有变量

在类中,可以使用闭包来隐藏类内部的变量,从而避免外部访问和修改该变量。例如,我们可以使用闭包来创建一个私有变量,如下所示:

class MyClass {  
  private variable = null;

  constructor() {  
    this.variable = await fetchSomeData();  
  }

  setVariable(value) {  
    this.variable = value;  
  }

  getVariable() {  
    return this.variable;  
  }  
}

在这个例子中,MyClass 类有一个私有变量 variable,它使用闭包从外部请求数据。然后,在构造函数中,它将这些数据存储在 variable 变量中。通过使用 setVariablegetVariable 方法,我们可以修改和读取私有变量。