揭秘 JS 中的闭包

揭秘 js 中的闭包

需要掌握才能理解语言的复杂细节。不像我们创建数组或函数那样创建。一个 fn 返回另一个存储在 lhs 变量中的 fn。

const securebooking = function(){  let passengercount = 0;  return function(){    passengercount++;    console.log(`${passengercount} passengers`);  }}const booker = securebooking();booker();booker();booker();

登录后复制securebooking fn 在全局范围内执行。将在全局执行上下文上创建一个新的执行上下文。 每个执行上下文(ec)都有自己的变量环境及其所有变量。 ‘let passengercount = 0’ 在此 ec 内定义。它可以访问其父作用域的所有变量。返回一个新的fn,并将其存储在booker中。全局 ec 还将包含 booker 变量。现在 securebooking() 将从 ec 中删除并消失。 securebooking ec 环境不再活跃。但仍然正在访问在创建 fn 时定义的 passengercount 变量。不过,内部 fn 将能够访问外部 fn 内部定义的 passengercount 变量。这是由于关闭而发生的。 闭包使 fn 记住围绕 fn 或其 ec 的出生地定义的变量。booker 不是 fn,位于全局范围内。现在执行booker();第一次将在调用堆栈上创建一个 ec,并具有自己的变量。fn 可以访问创建 fn 的执行上下文的变量环境。安全预订。因此,booker 将有权访问 securebooking fn 变量环境中定义的变量。即使包含 fn 的 securebooking fn 的 ec 已从调用堆栈中弹出,fn 的诞生地(即定义)与其周围变量环境的这种连接也称为闭包。闭包:附加到 fn 的变量环境,与创建 fn 时的环境完全相同。作用域链在闭包期间被保留,即使 ec 消失了,可变环境仍然以某种方式存在于引擎中。因此,我们说 booker fn 对父 fn 是封闭的,包括我们这里没有的父 fn 参数。使用闭包,fn 不会失去与其出生地周围定义的变量的连接。如果变量不在当前作用域内,js 会在查找作用域链之前先检查闭包。假设如果有一个全局变量,即使这样,也会首先查找其闭包中定义的变量。闭包优先于作用域链。第一次运行 booker() 后,passengercount 的值会增加,登录控制台,然后 booker 从调用堆栈中弹出。执行移动到下一行,创建一个新的 ec,但闭包变量仍然存在。现有值增加并弹出 ec。这个过程第三次重复。

概括

defn:闭包是创建 fn 的 ec 的封闭变量环境,即使在该 ec 消失之后也是如此。

此外,闭包允许 fn 访问其父 fn 的所有变量,即使在父 fn 返回之后也是如此。 fn 保留对其外部作用域的引用,从而始终保留作用域链。

闭包确保 fn 不会失去与 fn 诞生时存在的变量的连接。它就像一个 fn 随身携带的背包。这个背包具有创建 fn 的环境中存在的所有变量。

我们不必手动创建闭包。此外,我们甚至无法显式访问封闭变量。闭包不是有形的 js 对象,即我们无法访问闭包并从中获取变量。它是 fn 的内部属性。要查看背包,“console.dir(booker);”
[[scope]] 将向您展示此 fn 调用的 ve。

[[]] 表示它是一个内部属性,我们无法从代码中访问它。

我们总是不需要从另一个 fn 返回一个 fn 来创建闭包。在下面的示例中,变量“f”甚至没有在 fn 内定义,因为它在全局范围内。即使在 g() 完成其 ec 之后,它也能够访问“a”变量。 ‘a’现在在‘f’的背包里。

let f;const g = function(){  const a = 23;  f = function() {    console.log(a*2); // 46  };};const h = function(){  const b = 777;  f = function(){    console.log(b*2); // 1554  };};g();f();console.dir(f);// f fn is reassigned using h fn. hence, old closure value i.e 'a' will be replaced with new value 'b' which can be verified using console.dir().h();f();console.dir(f);

登录后复制settimeout(callbackfntobecalled, 延迟);闭包变量比作用域链具有更高的优先级。

// Boarding Passengers using Closuresconst boardPassengers = function(n, wait){  const perGroup = n / 3;  setTimeout(function(){    console.log(`We are now boarding all ${n} passengers`);    console.log(`There are 3 groups, each with ${perGroup} passengers`)  }, wait*1000);  console.log(`Will start boarding in ${wait} seconds`);}boardPassengers(180, 3);

登录后复制

以上就是揭秘 JS 中的闭包的详细内容,更多请关注【创想鸟】其它相关文章!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至253000106@qq.com举报,一经查实,本站将立刻删除。

发布者:PHP中文网,转转请注明出处:https://www.chuangxiangniao.com/p/2669914.html

(0)
上一篇 2025年3月7日 12:51:18
下一篇 2025年3月6日 06:31:15

AD推荐 黄金广告位招租... 更多推荐

相关推荐

  • 电子书

    es6 (ecmascript 2015) 为 javascript 引入了多项新功能和语法改进。以下是最重要的 es6 语法的总结和示例: 1. let 和 const 关键字 es6 为块作用域变量引入了 let 和 const。 le…

    2025年3月7日
    200
  • JavaScript 中的五种作用域:开发人员深入探讨

    javascript 对变量的行为是由它的作用域决定的。理解范围是编写健壮、可维护的代码的基础。本文将探讨 javascript 中的五种主要作用域类型——全局、局部、块、函数作用域(和闭包)和作用域链。最后,您将清楚地掌握 javascr…

    2025年3月7日
    200
  • JavaScript 中的闭包

    你好, 在这篇文章中,让我们学习闭包。 闭包在 javascript 中至关重要,因为它们允许函数从其父作用域访问变量,即使在父函数关闭之后也是如此。这对于需要随着时间的推移记住数据的函数至关重要,例如回调函数或维护状态。这里要记住的一点是…

    2025年3月7日
    200
  • JavaScript 中的提升

    什么是 javascript 提升? 提升是指 javascript 中在执行之前进行声明的过程。首先处理变量和函数声明。因此,即使变量在声明之前被引用,也不会导致错误,而是返回 undefined。对于函数声明,整个函数被提升,这意味着它…

    2025年3月7日
    200
  • 了解 JavaScript 中的变量:初学者指南

    理解 javascript 中的变量:初学者指南 欢迎回到我们的 javascript 世界之旅!在这篇博文中,我们将深入探讨编程中的基本概念之一:变量。变量对于在 javascript 程序中存储和操作数据至关重要。我们将介绍什么是变量、…

    2025年3月7日
    200
  • JavaScript 中的临时死区 (TDZ) 和提升:

    JavaScript 中的临时死区 (TDZ) 和提升: 临时死区(TDZ):临时死区是指进入作用域(如块或函数)和声明变量之间的时间段。在此区域中,任何访问变量的尝试都将导致引用错误。 TDZ 存在于初始化之前使用 let、const 和…

    2025年3月7日
    200
  • 执行上下文和调用堆栈

    为顶级代码创建全局执行上下文,即不在任何 fn 内的代码。因此,首先执行 fn 之外的代码。fn-decln/exprsn 的 fn 主体内的代码仅在调用时执行。 执行上下文(ec) 一段js执行的环境。存储一些要执行的代码的所有必要信息,…

    2025年3月7日
    200
  • 适用于您日常工作流程的 ESEST 提示、技巧、最佳实践和代码片段示例

    es6 (ecmascript 2015) 对 javascript 进行了重大改革,引入了许多新功能,可以简化您的编码并提高项目的整体质量。 在这篇文章中,我们将介绍一些es2015 提示、技巧、最佳实践,并提供代码片段示例来增强您的日常…

    2025年3月7日
    200
  • 起重面试问答

    1. javascript 中什么是提升? 答案: 提升是执行上下文创建阶段为变量和函数分配内存的过程。在此过程中,为变量分配了内存,并为变量分配了值 undefined。对于函数,整个函数定义存储在内存中的特定地址,并且对其的引用放置在该…

    2025年3月7日
    200
  • TypeScript 中的 TSyringe 和依赖注入

    我不太喜欢像 nestjs 这样的大型框架;我一直喜欢以我想要的方式构建我的软件的自由,以及我以轻量级方式决定的结构。但在测试 nestjs 时我喜欢的是依赖注入。 依赖注入(di)是一种设计模式,它允许我们通过消除创建和管理类依赖关系的责…

    2025年3月7日
    200

发表回复

登录后才能评论