js中的闭包

什么是闭包?

闭包可以这样来理解:闭包是一个函数,它与普通函数之间区别在于,闭包可以访问另一个函数的作用域中的变量对象。闭包可以是一个匿名函数(lambda函数),任何函数都可以被理解为是闭包。

我们来看一个简单的例子:

function CSSer(title){
    return function (description){
        return title + "," + description;
    }
}
CSSer("CSSer")("关注web前端技术");  // CSSer,关注web前端技术

上面的例子中定义了一个函数CSSer,该函数的执行结果将返回一个匿名函数(闭包)。该匿名函数可以访问CSSer函数中的变量对象title,即使CSSer函数执行完毕,其返回的匿名函数仍然可以访问CSSer函数环境中的变量。

闭包与变量

从闭包的概念中可以了解到,闭包可以访问其外部函数的变量对象,既然是变量对象,必然是变量最终的值,而不是变量某一状态的值,下面看一个很常见的例子:

function captureElemIndex(elems){
    for(var i = 0, len=elems.length;i < len; i++){
        elems[i].onclick = function(){
            console.log(i);
        }
    }
}
var elems = document.getElementsByTagName("div");
captureElemIndex(elems);

上述例子用于实现当div被鼠标点击时捕捉其在整个DOM树中的索引位置,乍看是没有问题的,但当实际运行时,就会发现每次捕捉的索引值都是elems.length,而不是我们想要的结果。我们了解了闭包机制之后,很容易解释这个问题,并且给出解决方案:

function captureElemIndex(elems){
    for(var i = 0, len=elems.length;i < len; i++){
        elems[i].onclick = function(n){
            return function(){
                console.log(n);
            }
        }(i);
    }
}

执行环境

当函数被调用时,会创建一个执行环境。

当进入执行环境时,创建其作用域链,并把作用域链赋给函数的特殊内部属性[[scope]]。

然后使用this、arguments和形参初始化函数的活动对象(即执行环境的变量对象)。这里对于变量对象的初始化过程是有顺序的:

  1. this :所有活动的执行环境都有this值,它依赖并取决于代码执行时的caller。
  2. arguments :创建arguments对象作为函数的arguments属性,arguments对象是一个类数组集合,其length即函数实参的个数,其每一个索引的值与对应的函数实参都指向同一个值的引用。 函数的arguments属性不可被delete动态删除 。
  3. 函数参数 :创建同名标识符作为property添加到变量对象中。如果调用者提供的参数少于形参,则其它形参值为undefined;如果遇到多个同名形参,最后一个形参值将被保留,如果最后的形参也未被提供值,则其值同样是undefined。
  4. 函数声明 :创建以函数名字为标识符作为property添加到变量对象中,其值为创建的函数对象。如果存在同名的property,则替换掉。
  5. 变量声明 :创建以变量名字为标识符作为property添加到变量对象中,其值为undefined,如果之前变量对象中存在同名property,则其值不变。

从进入执行环境到退出执行环境,完成了函数中代码语句的执行过程,一般情况下,函数执行完毕其执行环境的变量对象将被销毁以释放内存。由于闭包仍保留着对其外部环境活动变量对象的引用,所以存在特殊性。即使其外部环境的作用域链被销毁,但它的活动对象仍保留在内存中直至闭包被销毁才会被释放。

延长作用域链

Javascript中有两个语句可以延长作用域链:try-catch语句的catch语句块、with语句。所谓延长作用域链即是说在作用域的最前端临时增加变量对象(unshift),该变量对象会在代码执行完毕后被移除(shift),不再深究。【完】


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值