JavaScript 的闭包是什么

左手的ㄟ右手 2022-06-17 03:59 267阅读 0赞

本文翻译自 w3schools:

  • 原文地址:https://www.w3schools.com/js/js_function_closures.asp
  • 译文地址:shixinzhang 的博客

JavaScript 中的变量有两种:

  • 全局变量
  • 局部变量

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

两种变量

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

  1. function myFunction() {
  2. var a = 4;
  3. return a * a;
  4. }

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

  1. var a = 4;
  2. function myFunction() {
  3. return a * a;
  4. }

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

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

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

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

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

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

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

变量的生命周期

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

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

计数器的困境

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

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

  1. var counter = 0;
  2. function add() {
  3. counter += 1;
  4. }
  5. add();
  6. add();
  7. add();
  8. // 现在计数器的值是 3

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

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

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

  1. function add() {
  2. var counter = 0;
  3. counter += 1;
  4. }
  5. add();
  6. add();
  7. add();
  8. // 我们想要的效果是 counter 等于 3,但它并没有这样

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

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

JavaScript 的嵌套函数

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

  1. function add() {
  2. var counter = 0;
  3. function plus() {
  4. counter += 1;}
  5. plus();
  6. return counter;
  7. }

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

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

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

我们需要使用闭包。

JavaScript 的闭包

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

  1. var add = (function () {
  2. var counter = 0;
  3. return function () {
  4. return counter += 1;}
  5. })();
  6. add();
  7. add();
  8. add();
  9. // 现在 counter 的值就是 3

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

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

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

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

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

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

发表评论

表情:
评论列表 (有 0 条评论,267人围观)

还没有评论,来说两句吧...

相关阅读

    相关 JavaScript 什么

    JavaScript 什么是闭包? 闭包是指有权访问另一个函数作用域中变量的函数,创建闭包的最常见的方式就是在一个函数内创建另一个函数,创建的函数可以访问到当前函数的局部

    相关 javascript什么

    什么是js闭包? Js闭包是前端面试时最常见的题目。而在实际开发过程中,也会经常因为不注意闭包而导致代码运行得不到自己想要的结果。 想要掌握闭包,就必须了解jav