便写高质量JavaSript的68个高效方法 >> 二章:变量作用域 >> 第11条:熟练掌握闭包
二章
第11条:熟练掌握闭包
理解闭包的三个基本事实:
1. javaSricpt允许你引用在当前函数以外定义的变量。
2. 即使外部函数已经返回,当前函数仍然可以引用在外部函数所定义的变量。
3. 闭包可以更新外部变量的值。
1. javaSricpt允许你引用在当前函数以外定义的变量。
function makeSandwich(){ var magicIngredient = "peanut butter"; function make(filling){ return magicIngredient + "and" + filling; } return make("jelly"); } makeSandwich(); //"peanut butter and jelly"
请注意内部的make函数是如何引用定义在外部makeSandwich函数内的magicIngredient变量的。
2. 即使外部函数已经返回,当前函数仍然可以引用在外部函数所定义的变量。
function sandwichMaker(){ var magicIngredient = "peanut butter"; function make(filling){ return magicIngredient + "and" + filling; } return make; } var f = sandwichMaker(); f("jelly"); //"peanut butter and jelly" f("bananas"); //"peanut butter and bananas" f("marshmallows") //"peanut butter and marshmallows"
与 1 的不同之处:f的值为内部的make函数,调用f实际上是调用make函数。
即使sandwichMaker函数已经返回,make函数仍能记住magicIngredient的值。
这是如何工作的:JavaScript的函数值包含了比调用他们时执行所需要的代码还要多的信息。而且,JavaScript函数值还在内部存储他们可能会引用的定义在其封闭作用域的变量。那些在其所涵盖的作用域内跟踪变量的函数被称为闭包。
make函数就是一个闭包,其代码引用了两个外部变量:magicIngredient 和filling。每当make函数被调用时,其代码都能引用到这两个变量,因为该闭包存储了这两个变量。
函数可以引用在其作用域内的任何变量,包括参数和外部函数变量。
更加通用的sandwichMaker函数
function sandwichMaker(magicIngredient){ function make(filling){ return magicIngredient + "and" + filling; } return make; } var handAnd = sandwichMaker("ham"); handAnd("cheese"); //"ham and cheese" handAnd("mustard"); //"ham and mystard" var turkeyAnd = sandwichMaker("turkey"); turkeyAnd("Swiss"); //"turkey and Swiss" turkeyAnd("Provolone"); //"turkey and provolone"
函数表达式(更方便地构建闭包的字面量语法)
function sandwichMaker(magicIngredient){ function make(filling){ return magicIngredient + "and" + filling; } }
3. 闭包可以更新外部变量的值。
实际上,闭包存储的是外部变量的引用,而不是他们的值的副本。
因此对于任何具有访问这些外部变量的闭包,都可以进行更新。
一个简单的惯用法box对象的例子。(他存储了一个可读写的内部值)
function box(){ var val = unfefined; return { set:function(newVal){ val = newVal; }, get:function(){ return val; }, type:function(){ return val; } }; } var b = box(); b.type(); //"undefined" b.set(98.6); b.get(); //98.6 b.type(); //"number"
这个例子产生了一个包含三个闭包的对象。
这三个闭包是set、get、type属性。他们都共享访问val变量。set闭包更新val的值,随后调用get和type查看更新的结果。
提示:
- 函数可以引用定义在其外部作用域的变量。
- 闭包比创建他们的函数有更长的生命周期。
- 闭包在内部存储其外部变量的引用,并能读写这些变量。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 零经验选手,Compose 一天开发一款小游戏!
· 通过 API 将Deepseek响应流式内容输出到前端
· AI Agent开发,如何调用三方的API Function,是通过提示词来发起调用的吗