闭包,一言以蔽之,就是函数和作用域链,通俗点就是函数内部使用了外面定义的变量。
我们从一个例子说起:
function foo(){
var a = 2;
var b = 3;
return function bar(){
console.log(a+b);
}
}
var baz = foo();
baz();
最后的结果,控制台会输出a+b的值,也就是5。
在这段代码里,出现了闭包,bar()就是函数,bar引用了外面定义的变量a和b。
那么作用域链又是什么呢?
来个官方解释:(红宝书)
当代码在一个环境中执行时,会创建变量对象的一个作用域链。它的作用是保证对执行环境有权访问的所有变量和函数的有序访问。它的前端始终都是当前执行代码所在环境的变量对象。
这些东西看起来好像很难理解。我们先从执行环境这个概念开始解释。
执行环境(有时也称作环境)定义了变量或函数有权访问的其他数据,决定了它们各自的行为。
比如说上面的例子中,共有三个执行环境:
- 全局环境,有一个函数foo和一个变量baz。
- foo的局部环境,有两个变量a和b和一个函数bar。
- bar的局部环境。
bar的局部环境中,没有变量,但是它可以访问foo的局部环境中的变量a和b。
但是在全局环境中不能直接访问foo的局部环境中的变量a和b。因为全局环境是foo局部环境的父执行环境。
最后我们再来看作用域链
下图可以形象地表示上面例子的作用域链
图中的矩形表示特定的执行环境。内部环境可以通过作用域链访问所有的外部环境,但外部环境不能访问内部环境的任何变量或函数。这些环境之间是有次序的。每个环境可以向外搜索,但反之不行。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。