理解js中的闭包
来源:互联网 发布:日本磁悬浮知乎 编辑:程序博客网 时间:2024/04/20 19:00
js的闭包比较抽象,主要涉及到js的几个其他的特性:作用域链,垃圾回收机制,函数嵌套,等等。
首先,来理解一下作用域链。所谓作用域链,就是寻找使用到的变量的索引。其内部规则为:函数自身变量放在最前边,把父级函数中的变量放在其次,以此类推到全局变量为止。当函数中需要查询一个变量的值时,js会沿着作用域链查找,一旦找到,不再继续;如果没有找到,返回undefined。
其次,理解一下js的内存回收机制。一般情况下,一个函数在执行时会为其定义的变量划分内存空间,当函数执行完,这些变量就会被回收。但是存在一个函数中嵌套另一个函数的情况,内部函数可能会调用外层函数的变量,这时,外层函数的变量就不能被js回收,所以js解释器在遇到函数定义的时候,会自动把函数和他所需要的外部变量一起保存起来。也就是构建一个闭包。
下面通过一个例子理解闭包的作用:
我们知道,函数内部的局部变量无法在外部访问,那么怎样才能访问到函数内部的局部变量呢。可以在函数内部嵌套函数,然后把嵌套函数返回。这样,我们就能拿到函数内部的局部变量了。
function fun(){ var value = "inner"; function func(){ console.log(value); } return func();}fun();
以上得代码,其实就是闭包。本质上,闭包就是将函数内部和函数外部连接起来的桥梁。
以下是闭包的另一个例子:
var result = new Array();function foo(){ for (var i = 0 ; i < 3 ; i++ ){ result[i] = (function(i){ return function () { console.log(i); } })(i); }}
测试
foo();result[0]();//0result[1]();//1result[2]();//2
如果不使用闭包,输出都是3.
下面总结一个闭包的作用:
1 匿名自动执行函数
很多情况下,函数只要执行一次,比如界面初始化。这时,就可以使用闭包,一方面,局部变量很快会被释放,另一方面,不会污染全局变量。
(function(){ for (var j = 0 ; j < 5 ; j++){ console.log(j); }})();console.log(j);//j不会获取到
2 面向对象,模拟类,封装
function People(){ var username ; this.getUsername = function(){ return username; } this.setUsername = function(name){ username = name ; }}var p = new People();p.setUsername("zhangsan");console.log(p.getUsername()); //zhangsan
使用闭包的注意点:
1)由于闭包会使得函数中的变量都被保存在内存中,内存消耗很大,所以不能滥用闭包,否则会造成网页的性能问题,在IE中可能导致内存泄露。
解决方法是,在退出函数之前,将不使用的局部变量全部删除。
2)闭包会在父函数外部,改变父函数内部变量的值。所以,如果你把父函数当作对象(object)使用,把闭包当作它的公用方法(Public Method),把内部变量当作它的私有属性(private value),这时一定要小心。
最后,写一道思考题看看你是否理解了闭包:
var name = "Outer";var object = { name: "Inner" , getName: function(){ return this.name; };};console.log(object.getName());
var name = "Outer";var object = { name: "Inner" , getName: function(){ return function(){ return name; }; };};console.log(object.getName()());
两者有什么区别?
第一个输出:Inner
第二个输出:Outer
- 理解js中的闭包
- 理解js中的闭包
- 理解js中的闭包
- 理解js中的闭包
- 深入理解js中的闭包
- js中的闭包之我理解
- js中的闭包之我理解
- js中的闭包之我理解
- js中的闭包之我理解
- js中的闭包之我理解
- js中的闭包之我理解
- js中的闭包之我理解
- 彻底理解js中的闭包
- 理解js闭包
- JS 闭包理解
- js闭包理解
- js闭包理解
- js闭包理解
- UVA 11552 - Fewest Flops 刘汝佳的动归练习
- 仗剑江湖,浪迹天涯
- 模拟器尺寸不对如何解决-启动图片
- Yii Web Service
- 【影评】《方糖》、《妈妈,别哭》
- 理解js中的闭包
- Android小Demo——OnDragListener
- 组合式MapReduce作业的执行
- 假期备战蓝桥杯stm32学习笔记(四)
- List
- 消亡的宿命——记乡村小学的落败
- android开发游记:关闭所有Activity安全退出应用的方法总结
- Androidx学习笔记(2)-- ADB常用指令
- 系统学习机器学习之SVM(二)