深度理解javascript 闭包

闭包是javascript的一个难点,很难理解。但也是其显著的特性之一。掌握之后,可以实现很多很飘逸的功能。

理解闭包有2个关键点

1.作用域链

2.函数作为一个变量


1.作用域链

在javascript中,不像强类型语言是块级作用域,也就是局部变量只在一个花括号内部有效,而是函数作用域,局部变量在整个函数里面有效并且在内部嵌套的函数里面也有效。每执行一个函数就会创建一个作用域对象,嵌套的函数,作用域对象就会以链表的形式连接。当访问一个属性的时候,会现在当前作用域寻找,没有就往上级的作用域中寻找,都没有就返回undefined。

       var a = 'aaa';
       var fun =  function (){
            alert(a);
            var a = 'ccc';
            alert(a);
        }
这个例子,按理说fun是window对象的内部函数,应该可以访问window对象的属性的,但是alert() 为undefined,原因是javascript的解释器将var提前了。

换句话说,当执行fun的时候,开辟了新的执行作用域,这时声明提前,由于a与外部变量重名,外部a会被隐藏,内部访问的都是里面的a,所以alert的时候,还没有执行到赋值语句,所以是undefined。从这里也可以看出,在函数内,只要声明了变量,那么在整个函数内都可用,而与在哪里定义无关。


2.函数变量

在javascript中我们可以直接返回一个函数,也可以直接把函数赋值给一个变量。所以我们常会看到这种写法

     function f1(){
         var aa = 99;
         function f2(){
             aa++;
         }
         return f2();
     }

       var fff = f1();
       fff();

函数f1直接返回了f2,其实f2就是一个闭包了。我们可以稍微狭义一点理解,闭包就是一个引用了外部函数变量的函数。f2是可以操作f1的变量的,现在又把f2的引用赋值给了fff,所以当f1执行完毕之后,其作用域不会消失,因为还有其他函数引用他内部的变量。这就实现了,保存执行环境的功能。这在很多时候是非常有用的。


3.闭包

现在我们可以正式来说闭包了。

闭包有2个主要的功能

1.给予外部访问函数内部的能力

2.保存变量或者执行环境不会被回收

for(var i =0; i<link.length; i++){ 
    link[i].onclick = function(){ alert(i); }; 
}

这是一个非常经典的例子,执行结果,i一直是最后一个。原因是当调用点击事件的时候,for循环已经执行完毕了。所以i一直是最后一个。有2中解决办法

方案1、闭包

for(var i =0; i<link.length; i++){ 

link[i].onclick = (function(i){
return function(){  
alert(i);
};
})(i);
}

我们的目的就是保存每次执行到onclick定义时的i值。所以用了()()小括号,返回函数表达式的值,让函数在定义后立即执行,这个时候会新建一个作用域,而我们在内层又创建了一个函数,让它引用该作用域的变量,从而形成闭包,使得它不会被回收。这样我们就保存了每个i值在不同的作用域中。很明显,闭包会占用更多的资源, 而且要注意对象间的循环引用,否则会造成内存溢出。


方案2、属性

我们的目的就是保存每次执行到onclick定义时的i值,那么把i保存为当前对象的一个属性就ok,link[i].index = i;  然后在onclick函数里面直接调用属性,this.index即可。这种方式简单,而且方便。



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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值