[JavaScript] JS闭包(closure)的理解
[JavaScript] JS闭包(closure)的理解
明确两点:
1. function 是一个对象,他和数组,Object地位一样
2. JavaScript 的变量的作用域为链式作用域,即:子函数可访问父函数的变量,反之不能被访问
闭包的概念:
闭包的概念和JS解释器有关,JS解释器在遇到函数定义的时候,会自动把函数和他可能使用的变量(包括自身自身内部定义的变量、父级函数和祖父级函数的自由变量)一起保存起来,也就是构建一个闭包。这些变量将不会被内存回收机制所回收,知道内部函数不会被再被调用(例如删除或没有了指针)时才会销毁这个闭包,而没有任何闭包所引用的变量会在下一次内存回收启动时间回收。本质上,闭包是将函数内部和外部联系起来的桥梁!
闭包的三个特性:
1.函数嵌套函数
2.函数内部可以引用外部的参数或变量
3.参数或变量不会被垃圾机制所回收
闭包的缺点:
1.会使变量始终保持在内存中,会增加内存的使用量,使用不好容易内存泄露。
使用场景:
1. 实现对对象的封装,就像C++,C#,Java一样的 public,private 一样。
代码:
function ClassA() { var aa = 0; this.get_aa = function () { return aa; }; this.set_aa = function () { aa = aa + 1; } } var obj1 = new ClassA(); obj1.set_aa(); //1 alert(obj1.get_aa()); var obj2 = new ClassA(); obj2.set_aa(); obj2.set_aa(); alert(obj2.get_aa()); //2
注意:obj1与obj2 维护着两个闭包环境,彼此之间不会影响。
2.希望一个变量长期驻扎在内存中
解释:变量长期驻扎,不一定是坏事,如果我么维护的好,我们可以在浏览器当前会话页面做一层缓存。
代码:
var CachedSearchBox = (function () { var cache = {}, count = []; return { attachSearchBox: function (dsid) { if (dsid in cache) {//如果结果在缓存中 return cache[dsid];//直接返回缓存中的对象 } var fsb = new uikit.webctrl.SearchBox(dsid);//新建 cache[dsid] = fsb;//更新缓存 if (count.length > 100) {//保正缓存的大小<=100 delete cache[count.shift()]; } return fsb; }, clearSearchBox: function (dsid) { if (dsid in cache) { cache[dsid].clearSelection(); } } }; })();
3.可以读取函数内部的变量
JavaScript 的垃圾回收机制(GC):
1. 一个对象不再被引用,就会被GC回收;
2. 两个对象互相引用,并且不被第三者所引用,那么这两个对象也会被GC回收;
疑问解答:
1. 闭包为什么会造成内存泄露?举例说明。
答:首先,我们先说JS的垃圾回收机制的原理,当一个对象不再被引用时,那么就会被GC所回收,闭包就是函数嵌套,子函数由于被外部变量所引用,所以不会被GC所回收,又由于子函数依赖于父函数内的变量,所以父函数的变量也会一直在内存中,不会被GC锁回收,滥用就会造成浏览器性能问题。在IE浏览器中甚至会造成内存泄露。
2. 为什么IE浏览器更容易造成内存泄露?
答:见下一节学习的内容(浏览器的内存泄露)
3. 匿名只执行函数是什么样的?
答: 格式:(function(){ // 代码块 })() ,匿名函数的作用是可以创建新的命名空间,拒绝外界访问匿名函数中的对象,除非你允许。
真正的大师永远怀着一颗学徒的心。

浙公网安备 33010602011771号