理解js中的闭包

js的闭包比较抽象,主要涉及到js的几个其他的特性:作用域链,垃圾回收机制,函数嵌套,等等。
首先,来理解一下作用域链。所谓作用域链,就是寻找使用到的变量的索引。其内部规则为:函数自身变量放在最前边,把父级函数中的变量放在其次,以此类推到全局变量为止。当函数中需要查询一个变量的值时,js会沿着作用域链查找,一旦找到,不再继续;如果没有找到,返回undefined。
其次,理解一下js的内存回收机制。一般情况下,一个函数在执行时会为其定义的变量划分内存空间,当函数执行完,这些变量就会被回收。但是存在一个函数中嵌套另一个函数的情况,内部函数可能会调用外层函数的变量,这时,外层函数的变量就不能被js回收,所以js解释器在遇到函数定义的时候,会自动把函数和他所需要的外部变量一起保存起来。也就是构建一个闭包。
下面通过一个例子理解闭包的作用:
我们知道,函数内部的局部变量无法在外部访问,那么怎样才能访问到函数内部的局部变量呢。可以在函数内部嵌套函数,然后把嵌套函数返回。这样,我们就能拿到函数内部的局部变量了。

function fun(){
    var value = "inner";
    function func(){
        console.log(value);
    }
    return func();
}
fun();

以上得代码,其实就是闭包。本质上,闭包就是将函数内部和函数外部连接起来的桥梁。
以下是闭包的另一个例子:

var result = new Array();
function foo(){
    for (var i = 0 ; i < 3 ; i++ ){
        result[i] = (function(i){
            return function () {
                console.log(i);
            }
        })(i);
    }
}

测试

foo();
result[0]();//0
result[1]();//1
result[2]();//2

如果不使用闭包,输出都是3.

下面总结一个闭包的作用:

1 匿名自动执行函数
很多情况下,函数只要执行一次,比如界面初始化。这时,就可以使用闭包,一方面,局部变量很快会被释放,另一方面,不会污染全局变量。

(function(){
    for (var j = 0 ; j < 5 ; j++){
        console.log(j);
    }
})();
console.log(j);//j不会获取到

2 面向对象,模拟类,封装

function People(){
    var username ;
    this.getUsername = function(){
        return username;
    } 
    this.setUsername = function(name){
        username = name ;
    }
}
var p = new People();
p.setUsername("zhangsan");
console.log(p.getUsername()); //zhangsan

使用闭包的注意点:
1)由于闭包会使得函数中的变量都被保存在内存中,内存消耗很大,所以不能滥用闭包,否则会造成网页的性能问题,在IE中可能导致内存泄露。
解决方法是,在退出函数之前,将不使用的局部变量全部删除。
2)闭包会在父函数外部,改变父函数内部变量的值。所以,如果你把父函数当作对象(object)使用,把闭包当作它的公用方法(Public Method),把内部变量当作它的私有属性(private value),这时一定要小心。

最后,写一道思考题看看你是否理解了闭包:

var name = "Outer";
var object = {
    name: "Inner" ,
    getName: function(){
        return this.name;
    };
};
console.log(object.getName());
var name = "Outer";
var object = {
    name: "Inner" ,
    getName: function(){
        return function(){
            return name;
        };
    };
};
console.log(object.getName()());

两者有什么区别?
第一个输出:Inner
第二个输出:Outer

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值