js 闭包之一
既然说闭包的化,我们就先来说说函数。慢慢的进入进入正题
(1)函数申明
f1(); function f1(){ alert("1") }//结果 1
(2)函数定义
f1();
var f1=function(){
alert(''1")
}// 直接报错了
其实原因是这样的函数申明:会在代码执行之前提前加载到作用域中这样在执行发f1()的时候就可以找到了。但是函数的定义是:先在内存里卖弄创建了一块区域,之后通过一个f1() 指针指向这块区域,开始的时候这块区域是没有名字的.
函数的作用域链
var number="a"; var showNumber=function(){ alert(this.number); } function changeNumber(){ var anothernumber="b"; function savenumber(){ var tempnumber=anothernumber; anothernumber=number; number=tempnumber } savenumber(); } changeNumber(); showNumber() //结果是“b”
其实我的理解就是,在进行js 函数调用的时候,会为每一个函数自动的添加一个scope属性通过这个属性来指向一块内存,然后这个内存就会包含这个这个函数的上下文相关的变量,如果这个函数里面又包含了一个新的函数,那么又会自动的分配一块内存,当然这个函数又会自动的继承了他的上级所执行的变量(这个继承可能说的不太对感觉是这个意思?)
函数作用域链:示意图
其实可以这么理解哈。我们在带调用changnumber()的时候首先changenumber()这个函数的作用域链包括自己的(anothernumber 这个变量,然后就是savenumber()。最后就是上文的作用域,也就是number()和shownumber()这个全局的。这个时候savenumber 也会被执行那么他就会去继承他的上一级的作用域,和上上级的作用域,)那么这个时候savenumer去改变number 的值,这个时候number 的值就是b,最后当我们调用shownumber()的时候自然出现的值就是结果“b”了。
我看一个例子看看闭包产生的原因:
function compareObjectFunction(prop){ //匿名函数 return function(obj1>obj2{ if(obj1[prop]>obj2[prop]) return 1; else if(obj1[prop<obj2[prop]]) return -1; else return 0; }) } var o1={name:"Leon",age:23}; var o2={name:"Ade",age:28}; /* 在中这个时候变量并没有被释放,于是这个时候作用域就变大了 */ var compare=compareObjectFunction("age"); var rel=compare(o1,o2); alert(rel1)
我们看看他的作用域链
于是我们来解释一下到底是如何实现的。首先我们执行compareobjectfunction()的时候会产什么如下的作用域链Global和compareobject()这个。当compareobjecfunction执行完过后我们就会释放相应的作用域但是这个时候com这个匿名函数指向了相同的作用域,Global和compareobject()这个时候并不会发生释放这个作用域的动作,于是compar、这个就获取到相应的参数了。于是乎作用域就发生了扩大。这个就是闭包产生的原理。其实我的理解就是里面的函数调用了外部函数的变量(或者说扩大了函数的访问变量的范围)
下面我们再来看一个例子:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | function fn1(){ var fns= new Array(); for ( var i=0;i<10;i++){ fns[i]= function (){ return 1; } } return fns; } var fs=fn1(); for ( var i=0;i<fs.length;i++) { alert(fs[i]()) } |
注释:参考孔浩
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器
· DeepSeek如何颠覆传统软件测试?测试工程师会被淘汰吗?