当前位置: 首页 > news >正文

闭包的概念及使用场景介绍

概念:在JavaScript中,闭包(Closure)是指一个函数有权利访问定义在它外部作用域的任何变量。

function outerFn(outerVal) {return function innerFn(innerVal) {console.log('outerVal', outerVal)console.log('innerVal', innerVal)}
}const newFunction = outerFn('outside')
newFunction('inside')
// outerVal outside
// innerVal inside

内部函数有权利访问外部作用域的变量outerVal,而外部函数的变量已经被内部函数绑定。

使用场景

  1. 数据封装和私有化
    创建私有变量:闭包可以帮助我们封装私有变量,防止外部直接访问和修改。
    模块模式:使用闭包来实现模块化代码,每个模块都有自己的作用域,不会污染全局命名空间。
    function createCounter() {let val = 0;return {increment() {val++;},getVal() {return val;}}
    }
    let counter = createCounter()
    counter.increment()
    console.log(counter.getVal())// 1
    counter.increment()
    console.log(counter.getVal())// 2
    
  2. 柯里化(Currying)
    通过闭包,可以创建一个函数,这个函数被调用时不会立即执行,而是返回一个新的函数,新函数可以访问到原函数的参数。

function curry(func) {const len = func.length;// 返回一个新函数,这个新函数会处理参数的收集return function curried(...args) {// 如果传入的参数数量足够,直接调用原始函数if(args.length >= len) {return func.apply(this, args)} else {// 如果参数数量不足,返回一个新的函数,这个函数继续收集参数return function(...args2) {return curried.apply(this, args.concat(args2))}}}
}function add(a,b,c) {return a+b+c;
}const curriedAdd = curry(add);
console.log(curriedAdd(1,2,3))// 6
console.log(curriedAdd(1)(2,3))// 6
console.log(curriedAdd(1,2)(3))// 6
  1. 高阶函数
    高阶函数可以接收函数作为参数或将函数作为返回值,闭包使得这些函数可以访问并操作外部作用域的变量。
function formatNumberToLocaleString() {return function(number) {// 将数字转换为字符串,并使用正则表达式实现千分位分割return number.toLocaleString();};}const formatThousandSeparator = formatNumberToLocaleString();// 使用闭包实例格式化数字console.log(formatThousandSeparator(1234567.89)); // 输出 "1,234,567.89"

4.实现工厂函数
工厂函数可以创建并返回一个具有特定功能的对象,闭包可以用来保持每个对象的私有状态。

function carFactory(brand) {// 私有变量let engineState = 'off';return {startEngine: function() {engineState = 'on';console.log(`${brand} engine is now ${engineState}`)},stopEngine: function() {engineState = 'off'console.log(`${brand} engine is now ${engineState}`)},}
}const ford = carFactory('ford')
ford.startEngine()// ford engine is now on
ford.stopEngine()// ford engine is now off

5.事件处理和异步操作
在事件处理或异步操作中,闭包可以用来保持对特定作用域的引用,即使是在回调函数执行时作用域已经消失。


// 假设有一个元素列表
const items = document.querySelectorAll('.item');// 创建一个闭包来处理点击事件和异步操作
function createEventHandler(itemIndex) {return function(event) {// 从服务器获取数据fetchDataFromServer(itemIndex).then(data => {console.log(`Item ${itemIndex} data:`, data);}).catch(error => {console.error(`Error fetching data for item ${itemIndex}:`, error);});};
}// 为每个项目添加事件监听器
items.forEach((item, index) => {// 使用闭包来保持 itemIndex 的状态item.addEventListener('click', createEventHandler(index));
});// 模拟从服务器获取数据的异步函数
function fetchDataFromServer(itemIndex) {return new Promise((resolve, reject) => {setTimeout(() => {// 模拟成功或失败的情况if (Math.random() > 0.5) {resolve(`Data for item ${itemIndex}`);} else {reject(new Error(`Failed to fetch data for item ${itemIndex}`));}}, 1000);});
}
  1. 迭代器和生成器
    生成器函数利用闭包来保持其在每次迭代时的状态。
function createArrayIterator(array) {let index = 0;return {next: function() {if (index < array.length) {return { value: array[index++], done: false };} else {return { done: true };}}};}const myArray = [1, 2, 3];const iterator = createArrayIterator(myArray);console.log(iterator.next()); // { value: 1, done: false }console.log(iterator.next()); // { value: 2, done: false }console.log(iterator.next()); // { value: 3, done: false }console.log(iterator.next()); // { done: true }

闭包是JavaScript最好的语法之一。

http://www.lryc.cn/news/480238.html

相关文章:

  • qt5将程序打包并使用
  • 软件设计师-上午题-15 计算机网络(5分)
  • uniapp上拉刷新下拉加载
  • 【C++】【算法基础】快速排序
  • 数仓工具—Hive语法之窗口函数中的order by
  • 以旅游产品为例改写一篇系统架构风格的论文
  • 【Linux】linux编辑器-vim的命令及配置
  • 解决vite项目tailwindcss不生效!!(Vue3、tailwindcss失效)
  • ubuntu 20.04 NVIDIA驱动、cuda、cuDNN安装
  • Python世界:力扣题704二分查找
  • W55RP20-EVB-Pico评估板介绍
  • Flink安装和Flink CDC实现数据同步
  • 数字化转型助手 快鲸SCRM系统为企业营销赋能
  • 浅谈Agent
  • 绿色能源发展关键:优化风电运维体系
  • Sparrow系列拓展篇:对调度层进行抽象并引入IPC机制信号量
  • 天塌了!!!SQL竟也可以做预测分析?| 商品零售额的预测
  • VSCode本地C/C++环境配置
  • 【智能算法应用】淘金优化算法求解二维路径规划问题
  • Linux挖矿病毒(kswapd0进程使cpu爆满)
  • 【java】ArrayList与LinkedList的区别
  • 【LangChain系列6】【Agent模块详解】
  • JavaScript Cookie 与 服务器生成的 Cookie 的区别与应用
  • 深入了解Git、GitHub、GitLab及其应用技巧
  • ctfshow(316,317,318)--XSS漏洞--反射性XSS
  • Visual Studio2022版本的下载与安装
  • nodeJS程序如何引入依赖包
  • 建网站怎么建?只需几个步骤
  • 机器学习课程总结(个人向)
  • 数据分析-43-时间序列预测之深度学习方法GRU