[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(){ // 代码块 })() ,匿名函数的作用是可以创建新的命名空间,拒绝外界访问匿名函数中的对象,除非你允许。
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
posted @ 2019-04-30 15:55  NCat  阅读(179)  评论(0)    收藏  举报