作用域链和闭包

作用域链

JavaScript是基于词法作用域的语言(变量的作用域)
全局变量在程序中始终都是有定义的。
局部变量在声明它的函数体内以及其所嵌套的函数内始终是有定义的。
在这里插入图片描述
当一个块或函数嵌套在另一个块或函数中时,就发生了作用域的嵌套。因此,在当前作用域中无法搜索到某个变量时,引擎就会在外层嵌套的作用域中继续搜索,直到搜索到该变量,或查到全局作用域,这么一个查找过程形成的链条就叫做作用域链。
在这里插入图片描述
1.查看当前作用域,如果当前作用域声明了这个变量,可以直接访问
2.查找当前作用域的上级作用域,也就是当前函数的上级函数,看看上级函数中有没有声明,有就返回变量,没有继续下一步
3.再查找上级函数的上级函数,直到全局作用域为止,有则返回,无则继续
4.如果全局作用域中也没有,我们就认为这个变量未声明(xxx is not defined)

在JavaScript的最顶层代码中(也就是不包含在任何函数定义内的代码),作用域链由一个全局对象组成。
在不包含嵌套的函数体内,作用域链上有两个对象,第一个是定义函数参数和局部变量的对象,第二个是全局对象。
在一个嵌套的函数体内,作用域链上至少有三个对象。
例如:

在这里插入图片描述

闭包

闭包有两个作用:
第一个就是可以读取自身函数外部的变量(沿着作用域链寻找)
第二个就是让这些外部变量始终保存在内存中

在这里插入图片描述
闭包在 JavaScript 其实就是一个函数,在函数运行期被创建的,当上面的 函数被执行的时候,会创建一个闭包,而这个闭包会引用outher 作用域中的i。
下面就来看看 JavaScript 是如何来实现闭包的:
当执行 getNum 函数的时候, JavaScript 引擎会创建getNum 函数执行上下文的作用域链,这个作用域链包含了 getNum 执行时的活动对象,
同时JavaScript 引擎也会创建一个闭包,而闭包的作用域链也会引用 outher的活动对象,这样当 getNum 执行完的时候,虽然其执行上下文和活动对象都已经释放了outher,但是闭包还是引用着 outher的活动对象,所以结果为1。

发布了24 篇原创文章 · 获赞 0 · 访问量 747

猜你喜欢

转载自blog.csdn.net/weixin_45846263/article/details/104293588