正如标题所述,JAVAScript闭包对我来说一直有点神秘,看过很多闭包的文章,在工作使用过闭包,有时甚至在项目中使用闭包,但我确实是这是在使用闭包的知识 。
最近看到的一些文章,终于,有人用于一种让我明白方式对闭包进行了解释,我将在本文中尝试使用这种方法来解释闭包 。
准备【我从来不理解JavaScript闭包,直到有人这样向我解释它】在理解闭包之前,有个重要的概念需要先了解一下,就是 js 执行上下文 。
这篇文章是执行上下文 很不错的入门教程,文章中提到:
当代码在JavaScript中运行时,执行代码的环境非常重要,并将概括为以下几点:
全局作用域——第一次执行代码的默认环境 。
函数作用域——当执行流进入函数体时 。
(…) —— 我们当作 执行上下文 是当前代码执行的一个环境与作用域 。换句话说,当我们启动程序时,我们从全局执行上下文中开始 。一些变量是在全局执行上下文中声明的 。我们称之为全局变量 。当程序调用一个函数时,会发生什么?
以下几个步骤:
- JavaScript创建一个新的执行上下文,我们叫作本地执行上下文 。
- 这个本地执行上下文将有它自己的一组变量,这些变量将是这个执行上下文的本地变量 。
- 新的执行上下文被推到到执行堆栈中 。可以将执行堆栈看作是一种保存程序在其执行中的位置的容器 。
当一个函数结束时,会发生以下情况:
- 这个本地执行上下文从执行堆栈中弹出 。
- 函数将返回值返回调用上下文 。调用上下文是调用这个本地的执行上下文,它可以是全局执行上下文,也可以是另外一个本地的执行上下文 。这取决于调用执行上下文来处理此时的返回值,返回的值可以是一个对象、一个数组、一个函数、一个布尔值等等,如果函数没有return语句,则返回undefined 。
- 这个本地执行上下文被销毁,销毁是很重要,这个本地执行上下文中声明的所有变量都将被删除,不在有变量,这个就是为什么 称为本地执行上下文中自有的变量 。
文章插图
为了理解JavaScript引擎是如何工作的,让我们详细分析一下:
- 在第1行,我们在全局执行上下文中声明了一个新变量a,并将赋值为3 。
- 接下来就变得棘手了,第2行到第5行实际上是在一起的 。这里发生了什么? 我们在全局执行上下文中声明了一个名为addTwo的新变量,我们给它分配了什么?一个函数定义 。两个括号{}之间的任何内容都被分配给addTwo,函数内部的代码没有被求值,没有被执行,只是存储在一个变量中以备将来使用 。
- 现在我们在第6行 。它看起来很简单,但是这里有很多东西需要拆开分析 。首先,我们在全局执行上下文中声明一个新变量,并将其标记为b,变量一经声明,其值即为undefined 。
- 接下来,仍然在第6行,我们看到一个赋值操作符 。我们准备给变量b赋一个新值,接下来我们看到一个函数被调用 。当看到一个变量后面跟着一个圆括号(…)时,这就是调用函数的信号,接着,每个函数都返回一些东西(值、对象或 undefined),无论从函数返回什么,都将赋值给变量b 。
- 但是首先我们需要调用addTwo的函数 。JavaScript将在其全局执行上下文内存中查找名为addTwo的变量 。噢,它找到了一个,它是在步骤2(或第2 - 5行)中定义的 。变量add2包含一个函数定义 。注意,变量a作为参数传递给函数 。JavaScript在全局执行上下文内存中搜索变量a,找到它,发现它的值是3,并将数字3作为参数传递给函数,准备好执行函数 。
- 现在执行上下文将切换,创建了一个新的本地执行上下文,我们将其命名为“addTwo执行上下文”,执行上下文被推送到调用堆栈上 。在addTwo执行上下文中,我们要做的第一件事是什么?
- 你可能会说,“在addTwo执行上下文中声明了一个新的变量ret”,这是不对的 。正确的答案是,我们需要先看函数的参数 。在addTwo执行上下文中声明一个新的变量``x```,因为值3是作为参数传递的,所以变量x被赋值为3 。
- 下一步是:在addTwo执行上下文中声明一个新的变量ret 。它的值被设置为 undefined(第三行) 。
推荐阅读
- 教您win10电脑锁屏怎么设置
- 电脑为什么打不开指定的网站?什么是DNS解析我要如何设置DNS
- 此刻我独领风骚哪首歌里面的
- 花生芝麻豆渣饼的做法
- 我想种植黄茶在哪里购买黄茶苗,中国黄茶之乡在哪里
- 我的成长故事 我的故事作文600字
- 养老金怎么查?教你三步搞定!
- 康山黄茶收货时怎么辨别真伪,我在网上买了康山黄茶收货时怎么辨别真伪
- 小夫与胖虎6张图 小夫我要进来了是什么梗
- redis的多路复用是什么鬼