学习javascript闭包

闭包:是指有权访问另一个函数作用域变量的函数。

创建闭包的常见方式就是在一个函数内创建另一个函数。

理解如何创建作用域链以及作用域链的用途对于理解闭包非常重要。作用域链本质上是一个指向变量对象的指针列表,它只引用但不实际包含变量对象。无论在任何时候在函数中访问一个变量时,就会从作用域链中搜索相应名字的变量。

当某个函数被调用时,会创建一个执行环境(execution context)及相应的作用域链。然后使用arguments和其他命名参数来初始化活动对象(activation object)。但在作用域链中,外部函数的活动对象始终处于第二位,外部函数的外部函数的活动对象处于第三位……直至作用域终点的全局作用域。

一般来讲,当函数执行完毕后,局部活动对象会被销毁,内存中仅保存全局作用域(全局执行环境的变量对象),但是闭包的情况又有不同。

作用域链的这种配置机制引出了一个值得注意的副作用,即:闭包只能取得包含函数中任何变量的最后一个值。闭包保存的是整个变量对象而不是某个特殊的变量。
观察下面代码:

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

结果:
这里写图片描述

unction createFunctions(){
    var result=new Array();
    for( var i=0;i<10;i++){
        result[i]=function(num){
            return num;
        }(i);
    }
    for(var i=0;i<result.length;i++){
        console.log(result[i]);
    }
}
createFunctions();

结果为:
这里写图片描述

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

结果同上。

闭包中使用this对象:
我们知道在闭包中,this对象是在运行时基于函数的执行环境绑定的:在全局函数中,this指向window,而当函数被当作某个对象的方法调用时,this指向那个对象。不过,匿名函数的执行对象具有全局性,因此其this对象通常指向window,不过,通常由于编写闭包的方式不同,这一点可能不会那么明显。

如下代码,注意区分:

 var name = "The Window";
  var object = {
    name : "My Object",
    getNameFunc : function(){
      return function(){
        return this.name;
      };
    }
  };
  alert(object.getNameFunc()());
var name = "The Window";
  var object = {
    name : "My Object",
    getNameFunc : function(){
      var that = this;
      return function(){
        return that.name;
      };
    }
  };
  alert(object.getNameFunc()());

第二个代码和第一个代码的不同之处在于:在定义匿名函数前,我们把this对象付给了一个名为that的变量。而在定义了闭包之后,闭包仍然可以访问这个变量,因为它是我们在包含函数中特意声明的一个变量。

注意:this和arguments存在同样的问题,如果想访问作用域链中arguments对象,必须将对该对象的引用保存在另一个闭包也能访问的变量中。

以下几种情况也可能会导致this对象的改变:

var name="This window";
    var object= {
        name: "my object",
        getName: function () {
            return this.name;
        }
    };

        console.log(object.getName());//my object
        console.log((object.getName()));//my object
        console.log((object.getName=object.getName)());//this window

这个例子说明了,即使是细微的改变,都有可能意外改变this的值。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值