JS闭包的使用

一、关于闭包
    1、闭包:一个拥有许多变量和绑定了这些变量的环境表达式(通常是一个函数),因而这些变量也是该表达式的一部分。
    2、闭包的特点:
        1)、作为一个函数变量的一个引用,当函数返回时,其处于激活状态。
        2)、一个闭包就是当一个函数返回时,一个人没有释放资源的栈区。
        javascript允许使用内部函数——即函数定义和函数表达式位于另一个函数的函数体内。而且,这些内部函数可以访问他们所在的外部函数中声明的所有局部变量、
        参数和声明的其他内部函数。当其中一个这样的内部函数在包含它们的外部函数之外被调用时,就会形成闭包。
二、闭包的写法
    js中一切皆为对象,函数也是对象的一种。
    1、给函数添加一些属性
        function Circle(r){
            this.r = r;
        }


        Circle.PI = 3.14159;
        Circle.prototype.area = function() {
            return Circle.PI * this.r * this.r;
        }


        var c = new Circle(1.0);
        alert(c.area());
    2、声明一个变量,将一个函数当作值赋给变量。
            var Circle = function() {
            var obj = new Object();
            obj.PI = 3.14159;


            obj.area = function(r){
                return this.PI * r * r;
            }


            return obj;
        }


        var c = new Circle();
        alert(c.area(2.0));
    3、new一个对象,然后给对象添加属性和方法
        var Circle = new Object();
        Circle.PI = 3.14159;
        Circle.Area = function(r){
            return this.PI * r * r;
        }
        alert(Circle.Area(2.0));
    4、使用声明一个空对象,var obj = {}
        var Circle = {
            "PI":3.14159,
            "area":function(r){
                return this.PI * r * r;
            }
        };
        alert(Circle.area(2));
    5、直接声明函数
        var Circle = new Function("this.PI = 3.14159;this.area = function(r){return r * r * this.PI;}");
        alert((new Circle()).area(2));
三、闭包的用途
    通过使用闭包,我们可以模拟面向对象的代码风格;更优雅,更简洁的表达出代码;在某些方面提升代码的效率
    1、匿名函数自执行(有的函数只需要执行一次,其内部变量无需维护)
        在js中声明变量时没有加var关键字,会默认添加到全局对象的属性上去,这样会容易造成,别的函数可能误用这些变量,造成全局对象过于庞大,影响访问速度(变量的取值需要从原型链上遍历的)。
	var data = {
            table:[],
            tree:{}
        };
        (function(dm){
            for(var i = 0;i < dm.table.rows;i++){
                var row = dm.table.rows[i];
                for(var j = 0;j < row.cells;i++){
                    drawCell(i,j);
                }
            }
        })(data);
        创建了一个匿名函数,并立即执行它,由于外部无法引用他内部的变量,因此在函数执行完后会立刻释放资源,关键不会污染全局对象。
    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].clearSeleection();
                    }
                }
            };
        })();
        CachedSearchBox.attachSearchBox("input");
        这样我们二次调用的时候,就会从缓存中取到该对象。
    3、封装
        var person = function(){
            //变量作用域为函数内部,外部无法访问
            var name = "default";
            return {
                getName:function(){
                    return name;
                },
                setName:function(newName){
                    name = newName;
                }
            }
        }();

        print(person.name);
        print(person.getName());
        person.setName("abruzzi");
        print(person.getName());
    4、实现类和继承
        function Person(){
            var name = "default";
            return {
                getName:function(){
                    return name;
                },
                setName:function(newName){
                    name = newName;
                }
            }
        };
        var p = new Person();
        p.setName("Tom");
        alert(p.getName());
        var Jack = function(){};
        //继承自Person
        Jack.prototype = new Person();
        //添加私有方法
        Jack.prototype.Say = function(){
            alert("Hello,my name is Jack");
        };
        var j = new Jack();
        j.setName("Jack");
        j.Say();
        alert(j.getName());
        在此我们定义了Person,他就像一个类,我们new一个Person对象,并访问它的方法。然后又定义了jack,继承Person,并添加自己的方法。

猜你喜欢

转载自blog.csdn.net/u013308496/article/details/52065646
今日推荐