闭包的理解
2018-06-24 00:47:03来源:未知 阅读 ()
在整理笔记的时候发现,自己曾经做过一份关于闭包的笔记,觉得很有趣,当初学习的时候,满世界的去寻找答案,用百度去google一下,再用搜狐去搜狗一下,发现到头来还是要自己亲自去做测试,才能很深刻的去记住自己学过的知识,然后很无奈的否定当初自己那幼稚的做法。但不是不去查,而是在研究的时候,发现真的不懂了,才去针对闭包的某一个点去查,我喜欢有针对性的去寻找答案,而不是漫无目的。
全局变量和局部变量
言归正传,在说闭包之前,我认为,初学者必须先知道,JavaScript的全局变量和局部变量,并且还有他们的作用范围:
var n = 111;//全局变量 function f1(){ alert(n) } f1();//111 function 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);//100 if(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 defined function 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();//99 nAdd(); result();//100
n的值从99 到100 ,证明n存在内存当中,也就是f1周期完成后,被强制留下来了,而f1的留下来, 是因为f2变成了全局变量,而f2是依赖f1才能存活,所以f1被强制留下来,所以f1内部的 局部变量也能被f2使用(也是浪费内存的原因)
闭包的优点:
- 缓存
- 实现封装,防止变量发生污染
- 匿名自执行函数,匿名自执行函数可以减小内存消耗
闭包的缺点:
- 由于闭包内部变量优先级高于外部变量,所以多查找作用域链中的一个层次,就会在一定程度上影响查找速度。
- 内存浪费
- 处理不当,容易到时内存溢出
所以关于闭包,最好就是能不用就不用,如果非用不可,那就想办法保持闭包对象的数量很少甚至唯一。
标签:
版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有
下一篇:百度云学习资源整合
- Jquery插件写法笔记整理 2020-03-29
- javaScript 逻辑运算符使用技巧整理 2020-03-05
- 深入理解JavaScript是如何实现继承的 2020-02-25
- 高效率JavaScript编写技巧整理 2020-02-15
- JavaScript闭包函数访问外部变量的方法 2019-12-24
IDC资讯: 主机资讯 注册资讯 托管资讯 vps资讯 网站建设
网站运营: 建站经验 策划盈利 搜索优化 网站推广 免费资源
网络编程: Asp.Net编程 Asp编程 Php编程 Xml编程 Access Mssql Mysql 其它
服务器技术: Web服务器 Ftp服务器 Mail服务器 Dns服务器 安全防护
软件技巧: 其它软件 Word Excel Powerpoint Ghost Vista QQ空间 QQ FlashGet 迅雷
网页制作: FrontPages Dreamweaver Javascript css photoshop fireworks Flash