理解JAVASCRIPT 闭包
最近去面试了一家企业,结果非常灰心丧气,于是周末给自己定了一个目标
学好一门,学精通一门。不求多,只求懂。
最近看到一个概念“闭包”。
什么是闭包呢?
简单一点就是:看得到多和看得到少的区别。
上面这句话是我自己总结的,或许不太准确。
你能看到的多少这句话该如何理解呢?
下面随便丢一段代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | var name= "Peter" ; function outer() { var name= "Tom" ; function inner() { return this .name; } return inner; //返回函数inner,作为OUTER的一个返回值 } var flag=outer(); alert(flag()); //Peter |
大家也许会比较的疑惑,为什么返回的是Peter而不是Tom?
是不是认为编程的就近原则?
答案是:你还没有很好的理解闭包。
下面的一张图可以帮助大家理解一下,定义了一个flag对象,然后公共的函数是inner的父函数outer,
其实执行的是inner函数,因为outer函数返回对INNER函数的一个引用。
然后alert就是执行这个函数inner了。
我们要理解为什么是Peter而不是Tom,还需要了解一下闭包的作用域链。
那么,什么是作用域链呢?
看下面的代码;
1 2 3 4 5 6 7 8 9 10 11 | function num() { var number=0; //结果为4 //number=0; //结果为1 number++; } var number=4; num(); alert(number); |
如果运行上述代码,在function内加var 和不加var的区别是很大的。
这就是文章下面要提到的JAVASCRIPT链式结构;
如果不声明var,那就表示这是一个全局变量,记住这一点概念很重要。
而在函数内部加了var以后,试想一下,外面的这个number和里面的number就没有任何的关系了,
所以最后的结果是4,是全部的number起作用。
如果没加var关键字,那么number就是属于window下的,默认this指向window(this.number),
外层的var=4会被自动替换成1.
如果想alert的值为4,只有一个办法,把
1 2 | var number=4; num(); |
的顺序替换一下^_^。
闭包的特性之一,就是可以在函数外部通过对象调用到函数内部的局部变量。
就好像是C#中,私有的变量,必须通过getter,setter方法来进行调用一样。
说白了,闭包,就是和上面说的可以类比。
再回到上面的问题,为什么name是window的而非function内部的局部变量的呢?
大家有没有发现 var flag=outer()这句话。
其实flag对象是指向window的。
而这个outer函数其实是返回了一个inner的引用。
所以,inner里的this.name(等同于outer().name)也被变成了一个window对象的引用。
所以,闭包不仅可以在外面访问函数内部的变量,
还可以改变内部变量的值,所以这一点大家要注意了,
非常危险的!慎用闭包。
比如下面的代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | name= "Peter" ; var obj={ name: "yang" , innerFunc: function () { return function () { return this .name; } } } alert(obj.innerFunc()()); //Peter |
通过外面可以改变里面局部变量的值,让其指向全局变量。
所以这就相当于形成了一个setter方法。
大家使用闭包的时候一定要小心啊。
另外最后再补充一下:
JAVASCRIPT的链式原理:
1.内部函数B形式参数,实际参数,函数,内部变量。
2.内部函数B的原型prototype
3.外部函数A的形式参数,实际参数,函数,内部变量。
4.WINDOW对象,活动对象(链式的顶端)
另外还有一点要注意,就是在闭包的时候,因为外部可以调用到内部函数的变量,并且是Writable的,所以内部
函数变量是一个“可持久的”,就是可以不受JAVASCRIPT的垃圾回收机制的影响。
而内部函数的变量根据链式原理对于外部的变量也是可持久的,这就造成了内,外的变量都具有可持久性,
这就形成了闭包,不过造成了这些变量越积越多,在内存中,从而影响程序的效率。
这个时候,就要在函数调用结束后删掉一些不必要的变量,否则严重的会造成内存泄漏。
好了,写完了,话说那个人问我怎么写JQUERY的分页,我没答出来,好好努力吧
O(∩_∩)O哈哈~
祝大家周末愉快,我是新手,有写得不合理的地方,请多多指正。
1 | <br><br><br> |
__EOF__
作 者:ღKawaii
出 处:https://www.cnblogs.com/kmsfan/p/3734043.html
关于博主:一个普通的小码农,为了梦想奋斗
版权声明:署名 - 非商业性使用 - 禁止演绎,协议普通文本 | 协议法律文本。
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角【推荐】一下。您的鼓励是博主的最大动力!

出处:http://www.cnblogs.com/kmsfan
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
欢迎大家加入KMSFan之家,以及访问我的优酷空间!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器
· DeepSeek如何颠覆传统软件测试?测试工程师会被淘汰吗?