关于变量作用域,闭包的详解

var add_the_handlers = function(nodes){
    var i;
    for (i = 0; i < nodes.length; i += 1){
      nodes[i].onclick = function(e){
        alert(i);
      }
    }
};//糟糕的代码

 

 

我们先看这个糟糕的列子!这是javascript精粹上面的一个例子,一开始很是迷惑找了半天也找不到答案,最后自己啃书算是明白了一点(只自己明白了,不知道对否。)

先说几个名词:变量对象,作用域,作用域链,函数执行环境

再说几个和变量有关的知识:变量值分为基本类型值和引用类型值,而基本类型的值的复制是直接拷贝副本,而引用类型只是拷贝地址。但是在给函数传参时,全部是按值传递的,就像基本类型值变量的复制一样。

 

 我们来说列子。

      当调用这个add_the_handlers函数时,把节点数组传递到这个函数执行环境中,这时的执行环境中有两个变量一个是I,另一个则是nodes.length,而这两个变量当add_the_handlers这个函数执行完毕,而且也没有函数或者其他变量引用这个两个值,他就会消失(这里是作用域的概念)。

 

      但是当进入for循环后,当I为0的时间给节点0绑定上这个事件函数,也就是function(e){ alert(i); }这段代码,这里你要注意哦!这段代码没有人去调用,所以他不会执行,直到你触发这个节点为0的事件后这段代码才调用。所以当I值为1的时间同样给节点为1的绑定上一样的函数。直到节点数组的值绑定完。

 

      这时这个add_the_handlers函数执行环境中的变量I值就变成了节点数目的值。但当我们去触发所有这些节点事件时,开始调用绑定的事件函数,而这个事件函数的执行环境中压根没有这个I变量值,他该怎么办,他根据作用域链的关系只有往上一级的执行环境寻找这个I的值。所以对于上级的执行环境也就是

add_the_handlers这个环境中的I值,有人在引用着他所以这个函数执行完毕I值不能消失而节点数可以消失,但是不能消失他保存在哪里了呢?实际上市保存在变量对象中(这个东西看不到,也不能调用),而这时的I值就是循环后的结果了,也就是节点数,所以当你不管点击那个节点弹出来的都是总节点的数目(也就是nodes.length的值)

 

 经过改良的列子

         var add_the = function (nodes){
            var helper = function (i){
              return function (e){
              alert(i);
              }
            }
              var i;
              for(i = 0; i < nodes.length; i +=1){
                 nodes[i].onclick = helper(i);
              }

         }

 

当调用函数时,初始I值,给第0个节点绑定上这个函数helper(i),而这个I值根据函数传参的原理,会有一个同样的I值进入到helper这个执行环境中,而这个环境中返回出来的一个函数,在引用着helper这个函数执行环境中的变量I(因为返回出来的函数他没有I那个变量,只能往上级执行环境查找这个值),所以这个I值不会消失。其他同理

 

 

总结:

     当一个函数内部被返回出来的函数,可以访问到他外部的函数执行环境中的变量或者对象,也就是说可以访问到他被创建时间的上下文环境,这就被称为闭包!我们这个例子中第二个例子helper()被称为闭包

  闭包的特性:

 

1,闭包外层是个函数.

2,闭包内部都有函数.

3,闭包会return内部函数.

4,闭包返回的函数内部不能有return.(因为这样就真的结束了)

5,执行闭包后,闭包内部变量会存在,而闭包内部函数的内部变量不会存在.

 

闭包的应用场景

1、保护函数内的变量安全。

2、在内存中维持一个变量。

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值