JS闭包的使用

来源:互联网 发布:开淘宝店身份证照片 编辑:程序博客网 时间:2024/04/30 03:44
一、关于闭包
    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,并添加自己的方法。
1 0
原创粉丝点击