谈谈我对JavaScript中闭包的理解
2017-09-23 10:26
417 查看
**
个人博客开通啦!功能正在逐步完善中,大家可以访问http://www.codeliu.com
**
闭包是JavaScript中比较重要的一部分,也是比较难的一个知识点。在看了阮一峰老师的关于闭包的博客后,感觉对闭包的理解更清晰了,有需要的同学不妨一看。
http://www.ruanyifeng.com/blog/2009/08/learning_javascript_closures.html#comment-text 这是阮一峰老师文章的博客地址,下面我也做一个小小的总结,有兴趣的可以看看。
上面定义的n就是全局变量,在函数内部也可以访问到。
上面定义的n就是局部变量,函数调用后会立即销毁,所有再访问n就无法取得它的值了。
但注意在函数里的定义的变量前面一定要加var,否则就变成全局变量了。看下面的代码
上面的代码中定义n时没有加var,这样n就是全局变量,在外面依然可以访问n。
在上面的代码中,通过在函数内部定义另一个函数来获取n的值,这就是闭包。
在JavaScript语言中,只有在函数内部的子函数才能读取局部变量,因此可以把闭包理解为“定义在函数内部的函数”。
前面的代码已经展示了。
2.能让变量的值始终保存在内存中,不会被立即销毁。
前面我们说过,在函数内部定义的局部变量,在函数执行后,会被立即销毁,那闭包怎么让变量的值不被销毁呢?
在上面的代码中,第一个result()执行后,打印出1225,执行add()后,再执行result()后,打印出1226,说明n没有被立即销毁。
result被定义为全局变量,f1是f2的父函数,而f2赋值给result,成为全局变量,f2的存在又依赖于f1,所以f1也始终存在于内存中,不会再调用结束后,被垃圾回收机制(garbage collection)回收。
这段代码中另一个值得注意的地方,就是”nAdd=function(){n+=1}”这一行,首先在nAdd前面没有使用var关键字,因此nAdd是一个全局变量,而不是局部变量。其次,nAdd的值是一个匿名函数(anonymous function),而这个匿名函数本身也是一个闭包,所以nAdd相当于是一个setter,可以在函数外部对函数内部的局部变量进行操作。
1.由于闭包会使得函数中的变量都被保存在内存中,内存消耗很大,所以不能滥用闭包,否则会造成网页的性能问题,在IE中可能导致内存泄露。解决方法是,在退出函数之前,将不使用的局部变量全部删除。
2.闭包会在父函数外部,改变父函数内部变量的值。所以,如果你把父函数当作对象(object)使用,把闭包当作它的公用方法(Public Method),把内部变量当作它的私有属性(private value),这时一定要小心,不要随便改变父函数内部变量的值。
个人博客开通啦!功能正在逐步完善中,大家可以访问http://www.codeliu.com
**
闭包是JavaScript中比较重要的一部分,也是比较难的一个知识点。在看了阮一峰老师的关于闭包的博客后,感觉对闭包的理解更清晰了,有需要的同学不妨一看。
http://www.ruanyifeng.com/blog/2009/08/learning_javascript_closures.html#comment-text 这是阮一峰老师文章的博客地址,下面我也做一个小小的总结,有兴趣的可以看看。
1.变量的作用域
要理解闭包,首先我们要理解一下变量的作用域,分为全局变量和局部变量。全局变量,就是在任何一个地方都可以被访问到,局部变量,就是只能在一定范围内被访问。var n=1225; function f1(){ console.log(n); } f1(); //1225
上面定义的n就是全局变量,在函数内部也可以访问到。
function f1(){ var n=1225; console.log(n); } f1(); //1225 console.log(n); //undefined
上面定义的n就是局部变量,函数调用后会立即销毁,所有再访问n就无法取得它的值了。
但注意在函数里的定义的变量前面一定要加var,否则就变成全局变量了。看下面的代码
function f1(){ n=1225; } f1(); n; //1225
上面的代码中定义n时没有加var,这样n就是全局变量,在外面依然可以访问n。
2. 如何在外部访问函数内部的变量?
在正常情况下,因为在函数内部定义的变量都是局部变量,所以要在外部访问内部的变量,似乎是行不通的。function f1(){ var n=1225; function f2(){ console.log(n); } return f2; } var result=f1(); result(); //1225
在上面的代码中,通过在函数内部定义另一个函数来获取n的值,这就是闭包。
3.什么是闭包?
在上面的例子中,f2就是闭包。闭包是什么?我认为闭包就是能够读取其他函数内部变量的函数,是连接外部和内部的桥梁。在JavaScript语言中,只有在函数内部的子函数才能读取局部变量,因此可以把闭包理解为“定义在函数内部的函数”。
4.闭包的作用
1.能够读取函数内部的值前面的代码已经展示了。
2.能让变量的值始终保存在内存中,不会被立即销毁。
前面我们说过,在函数内部定义的局部变量,在函数执行后,会被立即销毁,那闭包怎么让变量的值不被销毁呢?
function f1(){ var n=1225; add=function(){ n++; } function f2(){ console.log(n); } return f2; } var result=f1(); result(); //1225 add(); result(); //1226
在上面的代码中,第一个result()执行后,打印出1225,执行add()后,再执行result()后,打印出1226,说明n没有被立即销毁。
result被定义为全局变量,f1是f2的父函数,而f2赋值给result,成为全局变量,f2的存在又依赖于f1,所以f1也始终存在于内存中,不会再调用结束后,被垃圾回收机制(garbage collection)回收。
这段代码中另一个值得注意的地方,就是”nAdd=function(){n+=1}”这一行,首先在nAdd前面没有使用var关键字,因此nAdd是一个全局变量,而不是局部变量。其次,nAdd的值是一个匿名函数(anonymous function),而这个匿名函数本身也是一个闭包,所以nAdd相当于是一个setter,可以在函数外部对函数内部的局部变量进行操作。
5.使用的闭包的注意事项
使用闭包虽然有好处,但也有不足。1.由于闭包会使得函数中的变量都被保存在内存中,内存消耗很大,所以不能滥用闭包,否则会造成网页的性能问题,在IE中可能导致内存泄露。解决方法是,在退出函数之前,将不使用的局部变量全部删除。
2.闭包会在父函数外部,改变父函数内部变量的值。所以,如果你把父函数当作对象(object)使用,把闭包当作它的公用方法(Public Method),把内部变量当作它的私有属性(private value),这时一定要小心,不要随便改变父函数内部变量的值。
相关文章推荐
- JavaScript进阶:谈谈对闭包的理解
- 谈谈我对JavaScript原型和闭包系列理解(随手笔记9)
- 谈谈我对JavaScript原型和闭包系列理解(随手笔记6)
- 谈谈我对JavaScript原型和闭包系列理解(随手笔记8)
- 谈谈我对JavaScript原型和闭包系列理解(随手笔记6)
- 谈谈我对JavaScript原型和闭包系列理解(随手笔记8)
- 谈谈我对JavaScript原型和闭包系列理解(随手笔记9)
- JavaScript基础---理解闭包问题
- 深入理解javascript原型和闭包(完结)
- javascript深入理解js闭包
- 深入理解JavaScript系列(16):闭包(Closures)
- 个人理解的javascript作用域链与闭包
- 理解 JavaScript 闭包
- 关于javascript中闭包的理解
- 深入理解javascript原型和闭包(12)——简介【作用域】
- javascript深入理解js闭包
- javascript深入理解js闭包
- Javascript的闭包理解
- 理解Javascript的闭包
- 闭包--javascript深入理解js闭包