本文章内容摘自此文章,仅作笔记用。
执行上下文
当代码在JavaScript中运行时,执行代码的环境非常重要,并将概括为以下几点:
全局作用域 —— 第一次执行代码的默认环境。
函数作用域 —— 当执行流进入函数体时。
执行上下文就是当前代码执行的一个环境与作用域。
当我们启动程序时,我们从全局执行上下文中开始。一些变量是在全局执行上下文中声明的。我们称之为全局变量。当程序调用一个函数时,会发生什么?
以下几个步骤:
-
JavaScript创建一个新的执行上下文,我们叫作本地执行上下文。
-
这个本地执行上下文将有它自己的一组变量,这些变量将是这个执行上下文的本地变量。
-
新的执行上下文被推到到执行堆栈中。可以将执行堆栈看作是一种保存程序在其执行中的位置的容器。
函数什么时候结束?当它遇到一个 return 语句或一个结束括号 }。
当一个函数结束时,会发生以下情况:
-
这个本地执行上下文从执行堆栈中弹出。
-
函数将返回值返回调用上下文。调用上下文是调用这个本地的执行上下文,它可以是全局执行上下文,也可以是另外一个本地的执行上下文。这取决于调用执行上下文来处理此时的返回值,返回的值可以是一个对象、一个数组、一个函数、一个布尔值等等,如果函数没有
return语句,则返回undefined。 -
这个本地执行上下文被销毁,销毁是很重要,这个本地执行上下文中声明的所有变量都将被删除,不在有变量,这个就是为什么 称为本地执行上下文中自有的变量。
词法作用域(Lexical scope)
一个函数可以访问在它的调用上下文中定义的变量,这个就是词法作用域(Lexical scope) 。
闭包
它是这样工作的,无论何时声明新函数并将其赋值给变量,都要存储函数定义和闭包。闭包包含在函数创建时所在作用域中的所有变量,它类似于背包。函数定义附带一个小背包,它的包中存储了函数定义创建时作用域中的所有变量。
当我们在声明一个新的函数时,会同时创建一个闭包,这个闭包包含了这个函数所在作用域内的所有变量。闭包中的变量不属于全局作用域,它只能被变量所在作用域内的函数所使用。