js之作用域链到闭包

时间:2022-05-25 16:05:03

一、作用域

  全局作用域和函数作用域(局部作用域)。

  一个变量的作用域就是源代码中定义这个变量的区域。

二、作用域链和闭包

  全局变量只有一个(window,globel),全局环境下每一个函数都会形成一个局部作用域。而 “函数的嵌套会形成一个个局部作用域嵌套着其余他一个个局部作用域”。这种 嵌套关系就是我理解的作用域链;

  基于词法作用域的规则,函数定义 时的作用域链到函数执行的时候依然有效。

  所以越嵌套到局部作用域中 的局部作用域中变量,需要从自身作用域开始,寻找变量的申明,如果没有,会顺着局部作用域嵌套一直找到全局作用域。特殊情况,一个在局部作用域中没有定义 ,直接赋值的变量,如果在作用域连上的局部作用域中也没有申明,会直接在全局下申明一个全局变量,并在赋值语句的地方进行赋值。

  我们把作用域链描述成一个对象列表 ,不是绑定的栈;

  每次函数调用的时候,都会为之创建一个新的对象AO(active  object),把找个对象加到作用域链中(对象 列表)。当函数返回时(执行完毕),就从作用域链中将其删除。

  如果这个函数中还嵌套着另一个函数a,那么a也会生成一个对象AO,并且 a得作用域链会指向这个a的AO对象 ,当函数返回时,会在a外部局部作用域中保存下来,那么他们 也会跟外部作用域的AO一起删除,当作垃圾回收。

  如果将这个函数的作为 返回值返回或者存储在某处 的属性中,这时就会有一个外部引用指向这个嵌套的函数,他就不会被当作垃圾回收。

三、代码逻辑图

function a(){

}

function b(){
function c(){}
c()
} a () ==>作用域类 [] ==> a的ao 全局window的GO
b () ==>作用域类 [] ==> b的ao 全局window的GO
执行到c()==>作用域类 [] ==> c的ao

                     b的ao//从这里开始来自b

                     全局window的GO

类似如上述逻辑代码,一个函数在全局下,他会在申明自己的AO执行上下文,然后把处于的位置的执行上下文加入到自己的队列中,形成一个类似数组的结构,我需要一个变量(方法),首先在自己的上下文中找,找不到,找我在处在的这个上下文,还找不到就继续往上找,一直找到window.

所以类似的,每个函数都有这个执行上文然后加上自己所处的执行上下文组成的自己的作用域链.

采用迭代 一直迭代到window结束这个作用域链的层层迭代.