闭包——可以在其他的执行上下文中,访问到函数的内部变量
闭包的概念 内部函数和其访问的上级变量共同形成的一个环境
作用域
在javascript中我们可以将作用域定义为一套规则,用来管理引擎如何在当前作用域以及嵌套的子作用域中根据标识符名称(变量名或者函数名)进行变量查找。
javascript中只有全局作用域和函数作用域(eval自动忽略。。。)
作用域和执行上下文是完全不同的概念。
javascript代码的整个执行过程,分为两个阶段,代码编译阶段与代码执行阶段。编译阶段由编译器完成,将代码翻译成可执行代码,这个阶段作用域规则会确定。执行阶段由引擎完成,主要任务是执行可执行代码,执行上下文在这个阶段创建。
image作用域链——是当前环境与上层环境的一系列变量对象组成,它保证了当前执行环境对符合访问权限的变量和函数的有序访问。
image image用数组表示作用域链,第一项作为作用域链的最前端,数组最后一项为作用域链最末端,所有最末端都是全局变量对象。
相比于包含关系,当前作用域与上层作用域称之为单方向通道更为贴切。
由于变量对象在执行上下文进入执行阶段时,就变成了活动对象。作用域链是由一系列变量对象组成,可以在单向通道查询变量对象中的标识符,这样就可以访问到上一层作用域中的变量了。
作用域链和函数调用栈是有区别的。
image image上例中 闭包被保存在了全局变量中,但是闭包的作用域链并不会发生任何改变。在闭包中,能访问到的变量,仍然是作用域链上能够查询到的变量。
image image闭包的应用场景: 柯里化,模块IIFE
也有一些反例:在baz函数中传入一个参数,并打印出来。调用时,全局的变量m传入。输出结果变为20。
image image由此课件 闭包形成的条件:
1.在函数内部创建新的函数;
2.新的函数在执行时,访问了函数的变量对象。
还有更有趣的例子
image image这个时候闭包变成了两个。
最后总结一下闭包:
闭包是在函数被调用执行的时候才被确认创建的。
闭包的形成,与作用域链的访问顺序有直接关系。
只有内部函数访问了上层作用域链中的变量对象时,才会形成闭包。
因此,我们可以利用闭包来访问函数内部的变量。
网友评论