JavaScript闭包和立即执行函数理解

JavaScript闭包

函数和对其周围状态(lexical environment,词法环境)的引用捆绑在一起构成闭包closure)。也就是说,闭包可以让你从内部函数访问外部函数作用域。这句话简单来理解就是闭包指的是函数嵌套函数,或者说定义在一个函数内部的函数,它是将该函数内部和函数外部连接起来的一座桥梁。这个内部函数可以使用外部函数的变量。

作用:闭包可以用在许多地方。它的最大用处有两个,一个是可以读取函数内部的变量,另一个就是让这些变量的值始终保持在内存中。

例1:请看下面代码:

function f1(){
    var n=999;
    nAdd=function(){n+=1};
    function f2(){
        alert(n);
    }
    return f2;
}
var result=f1();
result(); // 999
nAdd();
result(); // 1000

这段代码中result就是闭包f2函数,这个闭包可以访问并使用f1中的变量。这里result运行了两次,第一次的结果为999,第二次的结果为1000,如何理解呢?

为了更好地理解闭包的运行结果,我们把闭包和其周围环境分开来看。对应这里也就是f1里的前两行为周围状态,后面的f2函数为闭包。周围状态第一行声明了一个变量n=999,第二行声明了一个匿名函数表达式,并且nAdd没有使用var,因此它是一个全局变量,实际上它其实也是一个闭包。第一次运行result,匿名函数表达式没被调用,因此n仍为999,运行结果为999;在第二次调用result之前,调用了nAdd,从而使得n加了1,因此第二次运行结果为1000。同时,这两次的运行结果说明了变量n一直存在于内存中,没有在调用后被销毁。这证明了闭包可以将周围环境的变量值始终保存在内存中。

注意:如果这里nAdd使用了var关键字声明,则它就是一个局部变量,无法在外面调用了。

立即执行函数

立即执行函数(IIFE),顾名思义,也就是说这个函数是立即执行函数体的,不需要你额外去主动的去调用,一般情况下我们只对匿名函数使用IIFE,这么做有两个目的:一是不必为函数命名,避免了污染全局变量 二是IIFE内部形成了一个单独的作用域,可以封装一些外部无法读取的私有变量。

( function(){…} )()和( function (){…} () )是两种javascript立即执行函数的常见写法。要理解立即执行函数,需要先理解一些函数的基本概念:函数声明、函数表达式、匿名函数,这里不再赘述他们具体是什么。但值得注意的是,函数声明和函数表达式有两个不同点:1. Javascript引擎在解析javascript代码时会‘函数声明提升’(Function declaration Hoisting)当前执行环境(作用域)上的函数声明,而函数表达式必须等到Javascirtp引擎执行到它所在行时,才会从上而下一行一行地解析函数表达式。2. 函数表达式后面可以加括号立即调用该函数,函数声明不可以,只能以functionName()形式调用 。

例2:闭包和立即执行函数的使用

// 这段代码无法实现预期的效果,点击某个链接就出现这是链接几。
// 因为每次循环时i的值并没有保存下来,直到循环结束时,i的最终值为6(如果有6个a元素的话)
// 所以说无论点击那个连接,最终显示的都是I am link #6

var elems = document.getElementsByTagName('a');

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

    elems[i].addEventListener('click', function (e) {
        e.preventDefault();
        alert('I am link #' + i);
    }, 'false');

}

// 这个是可以实现效果,因为他在自执行函数表达式闭包内部
// i的值作为locked的索引存在,在循环执行结束以后,尽管最后i的值变成了a元素总数(例如10)
// 但闭包内部的lockedInIndex值是没有改变,因为他已经执行完毕了
// 所以当点击连接的时候,结果是正确的

var elems = document.getElementsByTagName('a');

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

    (function (lockedInIndex) {

        elems[i].addEventListener('click', function (e) {
            e.preventDefault();
            alert('I am link #' + lockedInIndex);
        }, 'false');

    })(i);

}

 

 

 

 

 

 

 

 

 

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值