前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >JavaScript 的闭包是什么

JavaScript 的闭包是什么

作者头像
张拭心 shixinzhang
发布2018-01-05 16:38:41
8670
发布2018-01-05 16:38:41
举报

本文翻译自 w3schools:

JavaScript 中的变量有两种:

  • 全局变量
  • 局部变量

使用 闭包 我们可以将全局变量变为局部变量。

两种变量

一个函数可以访问它内部定义的变量,比如这样:

代码语言:javascript
复制
function myFunction() {
    var a = 4;
    return a * a;
}

同时函数也可以访问它外部定义的变量,比如这样:

代码语言:javascript
复制
var a = 4;
function myFunction() {
    return a * a;
}

第一个例子中,a 是一个 局部变量

局部变量只能在创建它的函数内使用,其他范围(其他函数等)都访问不到它。

在第二个例子中,a 是一个 全局变量

在网页中,全局变量都属于 window 对象。

全局变量可以被当前页面的所有脚本使用或者修改。

和 Java 中相同的是: 全局变量和局部变量即使名称相同,也是不同的变量,修改其中一个不会影响另一个。

注意,不使用关键字 var,直接创建的变量,永远是全局变量,哪怕它是在函数中创建的!

变量的生命周期

全局变量的生命周期和创建它的网页/ window 声明周期一致。

局部变量则短一些,它在函数调用(不是创建)时创建,在函数结束时被删除。

计数器的困境

假设你想要用一个变量计数,你想要让所有函数都可以使用这个计数器。

你可以使用一个全局变量,然后提供一个方法来增加它:

代码语言:javascript
复制
var counter = 0;

function add() {
    counter += 1;
}

add();
add();
add();

// 现在计数器的值是 3

我们想要的效果是只能通过 add() 方法增加计数器的值。

但由于 counter 是全局变量,当前页面的脚本,不使用 add() 也能修改它。

那我们就把 counter 声明为局部变量,这样所有人要使用它只能通过 add() 方法:

代码语言:javascript
复制
function add() {
    var counter = 0;
    counter += 1;
}

add();
add();
add();

// 我们想要的效果是 counter 等于 3,但它并没有这样

每次调用 add() 方法,它都会将 counter 设置为 1.

JavaScript 的内部函数可以解决这个问题。

JavaScript 的嵌套函数

在 JavaScript 中,所有的函数都可以访问全局变量,除此外,它们还可以访问 “上一级函数” 中声明的变量(类似 Java 内部类)。

代码语言:javascript
复制
function add() {
    var counter = 0;
    function plus() {counter += 1;}
    plus();    
    return counter; 
}

在上面的例子中,内部函数 plus() 可以访问父函数的 counter 变量。

现在我们有了局部变量,也有了内部函数,只要能在最外部范围访问内部函数 plus(),我们就能逃离计数器的困境了。

哦对了,我们还需要只初始化一次 counter

我们需要使用闭包。

JavaScript 的闭包

还记得自调用函数 IIFE (Immediately Invoked Function Expression)吗?它做了什么?

代码语言:javascript
复制
var add = (function () {
    var counter = 0;
    return function () {return counter += 1;}
})();

add();
add();
add();

// 现在 counter 的值就是 3

上述代码,先创建了一个自调用匿名函数,这个函数在创建时就进行了自调用,完成了 counter 的初始化。

然后将函数 {return counter += 1;} 赋值给 add 变量,add 就变成了函数。

关键的部分在于:add() 方法可以访问父函数声明的 counter 变量

counter 被匿名函数的作用域保护着,我们只能通过 add() 方法修改它。

这就是闭包,它让函数可以拥有“私有”变量。

闭包就是一个函数即使在父函数关闭之后,也可以访问父函数中的变量。

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2017-04-16 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 两种变量
  • 变量的生命周期
  • 计数器的困境
  • JavaScript 的嵌套函数
  • JavaScript 的闭包
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档