什么是闭包(javaScript)

本文详细解析了JavaScript中闭包的概念,通过实例说明了闭包如何使函数记住并访问其词法作用域,即使在外部执行。探讨了局部变量的生命延续,展示了闭包在实际编程中的应用。

定义(出自《你不知道的JavaScript(上卷)》):
当函数可以记住访问所在的词法作用域时,就产生了闭包,即使函数是在当前词法作用域之外执行。

词法作用域即静态作用域

用一些代码来解释一下上面的定义

function foo() {
    var a = 2;

    function bar() {
        console.log( a ); // 2
    }

    bar();
}

foo();

这是闭包吗?
从技术上讲也许是,但是根据前面的定义,确切的说不是闭包。
虽然这段代码中bar()确实访问了自己所在的词法作用域(即foo()的函数作用域),但是并没有记住自己所在的作用域



下面这段代码,则是清晰的展示了闭包

function foo() {
    var a = 2;

    function bar() {
        console.log( a );
    }

    return bar;
}
var baz = foo();

baz(); // 2 —— 朋友,这就是闭包的效果。

这段代码中bar()不仅通过var baz=foo()记住了自己所在的词法作用域,而且可以通过调用baz()来访问自己所在的词法作用域。即使函数是在当前词法作用域之外执行。


参见:《你不知道的JavaScript(上卷)》



2020年11月02日更

最新看了《javaScript的设计模式和开发实战》,觉得这里对闭包的讲解更容易理解,所以在这里做个笔记。

这里是从变量的生存周期切入,来讲解闭包。

对于全局变量来说,全局变量的生存周期当然是永久的,除非我们主动销毁这个全局变量。而对于在函数内用var关键字声明的局部变量来说,当退出函数时,这些局部变量即失去了它们的价值,它们都会随着函数调用的结束而被销毁:

var func = function () {
  var a = 1; // 退出函数后局部变量a将被销毁
  a++;
  console.log(a);
};
func(); // 输出:2
func(); // 输出:2
func(); // 输出:2
func(); // 输出:2

现在来看看下面这段代码:

var func = function () {
  var a = 1;
  return function () {
    a++;
    console.log(a);
  }
};
var f = func();
f(); // 输出:2
f(); // 输出:3
f(); // 输出:4
f(); // 输出:5

跟我们之前的推论相反,当退出函数后,局部变量a并没有消失,而是似乎一直在某个地方存活着。这是因为当执行var f= func();时,f返回了一个匿名函数的引用,它可以访问到func()被调用时产生的环境,而局部变量a一直处在这个环境里。既然局部变量所在的环境还能被外界访问,这个局部变量就有了不被销毁的理由。在这里产生了一个闭包结构,局部变量的生命看起来被延续了。

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值