博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
闭包的理解
阅读量:7086 次
发布时间:2019-06-28

本文共 2267 字,大约阅读时间需要 7 分钟。

  在整理笔记的时候发现,自己曾经做过一份关于闭包的笔记,觉得很有趣,当初学习的时候,满世界的去寻找答案,用百度去google一下,再用搜狐去搜狗一下,发现到头来还是要自己亲自去做测试,才能很深刻的去记住自己学过的知识,然后很无奈的否定当初自己那幼稚的做法。但不是不去查,而是在研究的时候,发现真的不懂了,才去针对闭包的某一个点去查,我喜欢有针对性的去寻找答案,而不是漫无目的。

全局变量和局部变量

言归正传,在说闭包之前,我认为,初学者必须先知道,JavaScript的全局变量和局部变量,并且还有他们的作用范围:

var n = 111;//全局变量function f1(){alert(n)   }f1();//111function f1(){var n = 123;}f1();alert(n);//n is not defined

正如上面代码的结果一样:在函数外部自然无法读取函数内的局部变量,那么函数内部定义的n就不能在外部使用,所以输出的是n is not defined

但函数内部的就一定是局部变量吗?就真的不能被外部所使用吗?答案是否定的

function f2(){var m = n = 12;}f2();alert(n);//12

如上代码所显示,n能被外部所所以,此时我们能得出一个结论: 函数内部声明变量的时候,一定要使用var命令。如果不用的话,你实际上声明了一个全局变量(一般不推荐使用这种不用var来定义的变量)。

此时就剩下一个问题了,什么情况才算局部范围呢?

在我们学习的一般情况下,函数的{}内,相对于window来说,就是局部变量,我们也可以尝试,在一个{}里面定义变量,然后在window全局下调用,如果输出的为//n is not defined,证明{}里面的是局部变量了,为什么这样说呢?不是所有的{}里面都是局部变量吗?(当初我也这样觉得的/(ㄒoㄒ)/~~)

for(var i = 10;i<100;i++){console.log(i);}alert(i);//100if(true){var i = 100;}alert(i);//100

在for循环和if判断语句的中定义的变量,在全局范围内能调用,然而,测试还没结束,接着看…..

function aa(){for(var i = 10;i<100;i++){console.log(i);}}alert(i);//i is not definedfunction aa(){ if(true){var i = 100;}}alert(i);//i is not defined

我们发现,原来if和for的里面所定义的变量的作用范围都是当前的作用域范围

闭包概念:

闭包概念其实有很多不同的版本,我这里用的是阮一峰的一个解释: ,我们先来看个例子

function f1(){        var n = 99;                function f2(){                         // var a = 2;                         alert(n);                }         // alert(a);//a is not defined        f2();}f1();

在函数中,我们的f2函数内可以访问到f1的变量n,但f1不能访问f2里面定义的 变量a,这里就是Javascript语言特有的”链式作用域“结构,子对象会一级一级地向上找所有父对象的变量。所以,父对象的所有变量,对子对象都是可见的,反之则不成立。

简单来说,儿子找老爸要资源种子,但是儿子不给老爸资源片子((✿◡‿◡))

在了解完函数的链式作用域,我们来看看这段代码

function f1(){// console.log(‘1’+this);var n = 99;nAdd = function(){
//全局变量console.log(‘nAdd的this:’+this);n+=1;}function f2(){console.log(‘f2的this:’+this);console.log(n);}console.log(‘f1的this:’+this);return f2;}var result = f1();//f2 赋给result;result是全局变量,则f2为全局变量,因为f2需要依赖f1才能存在(如果f1消失,则f2也会被清除,所以f1也存在内存中)result();//99nAdd();result();//100

n的值从99 到100 ,证明n存在内存当中,也就是f1周期完成后,被强制留下来了,而f1的留下来, 是因为f2变成了全局变量,而f2是依赖f1才能存活,所以f1被强制留下来,所以f1内部的 局部变量也能被f2使用(也是浪费内存的原因)

闭包的优点:

  1. 缓存
  2. 实现封装,防止变量发生污染
  3. 匿名自执行函数,匿名自执行函数可以减小内存消耗

闭包的缺点:

  1. 由于闭包内部变量优先级高于外部变量,所以多查找作用域链中的一个层次,就会在一定程度上影响查找速度。
  2. 内存浪费
  3. 处理不当,容易到时内存溢出

所以关于闭包,最好就是能不用就不用,如果非用不可,那就想办法保持闭包对象的数量很少甚至唯一。

 

转载于:https://www.cnblogs.com/itdansan/p/7823407.html

你可能感兴趣的文章
【分享】开源富文本编辑器之间的较量
查看>>
logback的使用和logback.xml详解
查看>>
Android Studio -- 关联源码
查看>>
leetcode Majority Element
查看>>
去除sql的前后半角全角空格
查看>>
图片在容器里水平垂直居中
查看>>
015PHP文件处理——文件处理flock 文件锁定 pathinfo realpath tmpfile tempname
查看>>
关系型数据库之MySQL
查看>>
算法笔记-二叉树
查看>>
编写一个在1,2,…,9(顺序不能变)数字之间插入+或-或什么都不插入,并输出计算结果总是100的所有可能性。...
查看>>
Java异常处理课后作业
查看>>
hrtf 旋转音效matlab实现
查看>>
__attribute__
查看>>
【Android每日一讲】2012.11.06 Android变脸 - 主题(Theme)实现
查看>>
redis 系列12 哈希对象
查看>>
QTP使用心得
查看>>
js/jq ajax+数组。个人整理
查看>>
mac 下批量转换文件类型
查看>>
何为DOM对象
查看>>
linux的yum仓库配置
查看>>