理解 JavaScript 中的闭包 - JavaScript 周刊

2025-06-05

理解 JavaScript 中的闭包 - JavaScript 周刊

如需定期更新,请订阅每周新闻通讯《每周更新》

在本文中,我们将了解什么是闭包以及为什么我们需要闭包之类的东西,理解 JavaScript 中的闭包 - JavaScript 周刊

上一篇文章:https://cloudnweb.dev/2019/06/understanding-generators-in-javascript-javascript-weekly/

什么是闭包?

简单来说,闭包不过是在另一个函数内部定义的函数。闭包可以访问所有局部变量、函数外部变量和全局变量。

问题陈述

为了更好地理解这一点,请考虑以下代码结果。

  1. 问题陈述
let name = "Ganesh";

function getMyName() {
  console.log("Name is "+name);
}

name = "Mani";

getMyName(); //what will be the output here?

这种情况在 Web 开发(前端和后端)中很常见。我们将定义一个函数并在稍后的某个时间点调用该函数。

2.问题陈述

function getMyName() {
  let name = "Ganesh";

  return function() {
    console.log(name);
  };
}

let name = "Mani";

// create a function
let myname = getMyName();

// call it
myname(); // What will it show? 

要理解这个概念,首先我们需要了解词汇环境的概念

词汇环境

词法环境只不过是维护特定函数的状态及其外部环境状态、变量。

每个内部函数都会有一个局部变量,内部函数还可以访问父函数变量和全局变量。

维护特定功能的范围只不过是一个词汇环境。

回到问题陈述...

现在,如果我们回到问题陈述,问题陈述 #1 将返回值为“Mani”

因为,自从我们将其定义为全局变量以来,该值就会更新。

现在,在问题陈述#2中,我们定义了一个名为getMyName()的函数。在函数内部,我们定义了一个名为name的变量,它只是一个父函数变量。

我们正在从getMyName()函数返回一个函数

现在,如果我们在全局上下文中定义名为name的相同变量并执行getMyName()

它不会改变它的值。因为getMyName()返回一个函数,而这个函数只是一个闭包,它将保存特定环境的变量状态和值

https://output.jsbin.com/qikuginowe

javascript 首先查看内部函数,然后查看父函数。最后,它将查看全局变量。

闭包——实际实施

使用闭包代替对象

如果你熟悉 OOPS 概念,你就会知道“ this ”的概念,它指的是类的上下文

让我们尝试使用 OO 概念编写一个函数,然后我们将看到如何使用闭包重写它。

function User(){

  this.firstname = "John";

  this.lastName = "Robert";
}

User.prototype.getFirstName = function getFirstName() {
  console.log(this.firstname);
}

User.prototype.getLastname = function getLastname() {
 console.log(this.lastName);
}

User.prototype.showFullName = function showFullName() {
   console.log(this.firstname+" "+this.lastName);
}

module.exports = User;

我们正在创建一个名为 user 的函数,并为特定用户函数添加函数getFirstNamegetLastNameshowFullName ,并使用这个关键字访问函数变量。

要调用这个特定的函数,我们需要创建它的新实例并调用特定的函数


let User = require('./user');

let data = new User();
data.showFullName();

它会向我显示类似“ John Robert ”的内容

现在,让我们看看如何使用闭包重写它

function User() {

  let firstName = "Will";

  let lastName = "Smith";

  return { 
   getFirstName : function () {
    console.log(firstName);
  },

   getLastName: function () {
      console.log(lastName);
    },

    showFullName :function () {
      console.log(firstName+" "+lastName);
    }
  }
}

module.exports = User;

我们像以前一样定义一个用户函数,然后不是绑定该函数,而是从父函数用户返回这些函数

注意:返回函数只不过是闭包。

现在,如果我想调用这个函数,我们必须做类似的事情

//using Closure in Javascript

let userClosure = require('./user_closure');

let closureresult = userClosure();

closureresult.showFullName()

它将返回“ Will Smith ”作为输出。

这是实时用例之一,可以尝试实现闭包而不是使用关键字。

测验:

尝试解决这个问题并在这篇文章中评论你的结果并向我解释它是如何工作的。

function doIncrement(){
  let counter = 0;

  return function(){
    counter ++;
    return counter; 
  }
}

let increment = doIncrement();

console.log(increment());
console.log(increment());
console.log(increment());
//What is the result ?

这就是本周的全部内容。尝试在实时用例中实现这一点,以便您可以从中掌握概念。

参考 :

https://medium.com/javascript-scene/master-the-javascript-interview-what-is-a-closure-b2f0d2152b36

我们将在接下来的文章中看到 JavaScript 的其他一些特性。

到那时,祝您编码愉快:-)

文章来源:https://dev.to/ganeshmani/understanding-closures-in-javascript-javascript-weekly-3050
PREV
使用 Node.js 进行 Web 抓取的终极指南什么是 Web 抓取?
NEXT
TypeScript 基础 - 权威指南