闭包和执行上下文

闭包: 我们可以这样简单理解一下,闭包其实只是一个绑定了执行环境的函数,这个函数并不是印在书本里的一条简单的表达式,闭包与普通函数的区别是,它携带了执行的环境,就像人在外星中需要自带吸氧的装备一样,这个函数也带有在程序中生存的环境。 执行上下文: 相比普通函数,javaScript函数的主要复杂性来自于它携带的环境部分,JavaScript 中与闭包环境部分相对应的术语是词法环境,比较复杂,需要处理this、声明变量、with等等一系列的复杂语法,在JavaScript中,词法环境只是JavaScript执行上下文的一部分。JavaScript标准把一段代码(包括函数),执行所需的所用信息定义为:'执行上下文'。 let 是 ES6 开始引入的新的变量声明模式,比起 var 的诸多弊病,let 做了非常明确的梳理和规定。为了实现 let,JavaScript 在运行时引入了块级作用域。也就是说,在 let 出现之前,JavaScript 的 if for 等语句皆不产生作用域。 以下语句会产生let使用的作用域:for、if、switch、try、catch、finally。 在JS中,函数其实就是闭包,不管该函数内部是否使用外部变量,它都是一个闭包,如果定义闭包的那样,有环境和表达式组成,作为js函数,环境为词法环境,而表达式就是函数本身。而词法环境是执行上下文的一部分,执行上下文包括this的绑定,词法环境和变量环境,词法环境是随着执行上下文一起创建的,在函数、脚本、eval执行时创建。 理解闭包,首先需要理解闭包是什么类型的东西,闭包实际上指的是函数,搞清楚问题的对象究竟是谁,而很多人会把环境、作用域等其他东西当作闭包,是对闭包的概念类型的错误理解。那么知道了闭包是函数,那么闭包是什么样的函数呢?也就是含有环境的函数,很明显,在js中,任何一个函数都有自己的环境变量,这个环境变量让我们可以去找到定义的变量内部的this、外部作用域。 很多人认为,要让一个函数能去访问某个应该被回收的内存空间,但由于函数存在对该内存空间的变量的引用而不可回收,这样才形成了闭包。那么试问一下,这里你到底是把这个内存空间当作闭包呢?还是引用这块内存空间的函数当作闭包呢?假如是前者,则和把环境当闭包的人犯了同样的错误,假如是后者,现在的这个函数实际上和你定义的普通函数本质上没有区别,都含有自己的环境,只不过这个函数的环境多了一些,但本质没有区别。