天天看点

JavaScript闭包闭包

版权声明:本文为博主原创文章,转载请注明出处。 https://blog.csdn.net/twilight_karl/article/details/60592592

闭包

1,闭包可以让局部变量驻留在内存中,而不会重复初始化

2,过度使用会导致内存占用过高,因此用完后应及时解除引用:

b = null
function add(){
            var num = 100;
            return function(){
                return num++;
            };
        };

        var fun3 = add();   // 获得闭包函数,add函数只初始化一次
        alert(fun3());      // 101
        alert(fun3());      // 102
        alert(fun3());      // 103
        alert(fun3());      // 104
        fun3 = null;        // 过多的使用闭包会占用大量内存,使用完后要释放闭包函数:
        alert(fun3());      // 报错           

以循环里的匿名函数的取值为例,分三种情况:

<1>: 返回的闭包函数由于是在sum执行完后再执行,所以返回的值都是5.数组中保存的是匿名函数,需要用函数的方式调用。

// 001  
        function sum(){
            var arr = new Array();
            for(var i=0;i<5;i++){
                arr[i] = function(){
                    return i;
                }
            };

            return arr;
        };

        var data = sum();
        for( var i=0;i<5;i++){      // 全部是5
            alert(data[i]());
        }           

<2>: 利用函数的自我执行即时的给数组赋值,返回的数组内容是数字

// 002 
        function sum(){
            var arr = new Array();
            for(var i=0;i<5;i++){
                arr[i] = (function(num){        // 匿名函数的即时执行
                    return num;
                })(i);
            };

            return arr;
        };

        var data = sum();
        for( var i=0;i<5;i++){      // 正常
            alert(data[i]);
        }           

<3>: 使用函数的自我执行的同时返回一个匿名函数,返回的数组需要当成函数调用

// 003 
        function sum(){
            var arr = new Array();
            for(var i=0;i<5;i++){
                arr[i] = function(num){     // 匿名函数的即时执行
                    return function(){
                        return num; 
                    };
                }(i);
            };

            return arr;
        };

        var data = sum();
        for( var i=0;i<5;i++){      // 正常
            alert(data[i]());
        }           

闭包中的this

闭包中的this指向window,闭包并不属于某个对象的属性和方法。解决方法:对象冒充。

var flag = "window";

    var box = {
        flag : "box",
        fun : function(){
            return function(){
                return this.flag;
            }
        }
    };
    alert(box.fun()());     // 闭包的this指向window           

可以使用以下的方法解决,不直接使用闭包中的this,而是保存普通函数中的this,再在闭包中调用:

var box2 = {
        flag : "box",
        fun : function(){
            var sss = this;
            return function(){
                return sss.flag;
            }
        }
    };
    alert(box2.fun()());        // box2           

使用call或者apply更改作用域也可以解决问题:

var box3 = {
        flag : "box",
        fun : function(){
            return function(){
                return this.flag;
            }
        }
    };

    alert(box3.fun().call(box3));           

私有作用域

JavaScript没有块级作用域,但是自我执行的匿名函数有私有作用域,作用域中的变量在执行完后就被销毁,在作用域外无法被调用。可以减少全局变量的使用。

(function(){
        for(var i=0;i<5;i++){}
    })();
    alert(i);       // undefined           

私有变量

this.属性或this.方法表示的是共有方法和属性。但是在方法中用var声明的方法或属性是私有属性,外部无法调用,用该函数创建的对象也无法使用私有属性。

function Person(str){
            var name = str;         // 私有属性
            var fun = function(){   // 私有方法
                return name+"###";
            };
        };
        var tom = new Person("Tom");

        alert(tom.fun());       // 报错
        alert(tom.name);        // 报错           

继续阅读