谈谈自己对作用域链和闭包的理解

今天我们学习了 Javascript 中作用域链和闭包的相关知识,在此写一篇文章来总结一下,加深自己对这两个知识点的理解。


作用域链:


要了解作用域链,必须先明白执行环境(execution context ),执行环境定义了变量或函数有权访问的其他数据。定义了他们的行为。每个执行环境都有一个和它关联的变量对象,在这个执行环境中的所有变量和函数都保存在这个对象中。在web浏览器中,全局执行环境的变量对象就是 window 对象,所有的全局变量和函数都是 window 的属性和方法。而对于函数来说,变量对象就是这个函数的 活动多象。

作用域链与一个执行环境相关,作用域链用于在标示符解析中变量查找。

函数也是对象,也拥有属性和方法,每个函数中都有一个内部属性 [[ Scope ]],这个属性指向函数的作用域链。作用域链中储存的是每个执行环境中相关的变量对象。当申明一个函数,那么就会创建出这个函数的作用域链,这个作用域链此时只包含一个变量对象,就是 window 对象。当调用这个函数的时候,会先创建一个执行环境,这个执行环境有自己的作用域链,作用域链里初始化为这个函数里所有的变量和对象,再创建这个执行环境相关的变量对象,变量对象会储存这个函数里所有的变量和对象。把变量对象储存在作用域的顶端,执行函数时,变量查找从作用域顶端开始查找,直到作用域的末端。就形成了作用域链。

请看下列代码:

谈谈自己对作用域链和闭包的理解_第1张图片

内部函数的作用域图:

谈谈自己对作用域链和闭包的理解_第2张图片

闭包:

谈谈自己对作用域链和闭包的理解_第3张图片

在上面的代码中,createSumFunction函数返回了一个匿名函数,而这个匿名函数使用了createSumFunction函数中的局部变量(参数),即使createSumFunction这个函数执行结束了,由于作用域链的存在,他的局部变量在匿名函数中仍然可以使用,这个匿名函数就是闭包。

闭包用一句简单的话来描述:

闭包就是指有权访问另一个函数作用域中的变量的函数。

闭包是一种特殊的对象。它是由函数和创建此函数的环境组成。环境由创造闭包时作用域中所有的局部变量组成。上面代码中,sumFun就是一个闭包,由匿名函数和创建闭包是所申明的num1 和num2两个局部变量组成。

闭包的应用:

请看下面代码:

谈谈自己对作用域链和闭包的理解_第4张图片

以上代码中,虽然函数申明在num++之前。但是函数调用的时候num 已经++ 过了,所以最后的num值为6.由此可知:闭包中使用局部变量的值,一定是这个变量的最新值(最后的值)。

请看一下代码:

谈谈自己对作用域链和闭包的理解_第5张图片

此列是经典的for循环问题。当运行的时候会发现,无论你点击哪个按钮,都是弹出 “我是底4个按钮”,这就是闭包所导致的。因为所取 i 的值,总是最新的值。

解决方案:

谈谈自己对作用域链和闭包的理解_第6张图片

好了,本次总结就到此结束了,因为刚刚学习,总结得不好,也不到位,希望各位能够理解支持,也能把自己的建议告诉我,我定积极进取。

你可能感兴趣的:(谈谈自己对作用域链和闭包的理解)