- 作用域与作用域链
① 作用域属于一个函数,一个函数产生了不一样的作用域
② 函数名.[[scope]] 函数的隐式属性
③ [[scope]] 指的就是作用域,其中存储了运行期的上下文的集合,而这一集合就是作用域链
④ 查找变量:从作用域链的顶端依次向下查找(在那个函数里面查找变量,就上那个函数的作用域链的顶端依次向下查找变量)
2. 函数的执行期上下文
① 当函数执行的前一刻,会创建一个称为执行期上下文的内部对象AO
② 一个执行期上下文定义了一个函数执行时的环境(也就是函数预编译创建AO后下面的步骤操作),函数每次执行时对应的执行上下文都是独一无二的
③ 多次调用一个函数会导致创建多个执行上下文,当函数执行完毕,它所产生的执行上下文会被销毁
3 . 用代码和图解说明函数执行时的作用域链和执行上下文问题
① 代码
function a(){ function b(){ var b = 234; } var a = 123; b(); } var glob = 100; a();
|
② 说明
代码执行说明 1. a被定义时,在其自己所处的环境下(全局环境)创建了一个执行期上下文(GO)将其放在 其作用域链的顶端,即0位处 2. a被执行时,会再次创建一个属于自己函数体的执行期上下文(AO)并将这个AO放在其作用域 链的顶端,即0位处,原先的那个GO会被向下推一位,位于作用域链的1位处 3. b被定义时,会在其自己所处的环境下创建执行期上下文,此时它处于a的函数体内,因此它会 继承a原先已经创建好的作用域链,即a的AO和在全局环境下创建的GO 4. b被执行时,会创建属于自己函数体的执行期上下文(AO)并将其放在其作用域链的顶端,即0 位处,原先继承的a的AO和GO会以此向下推,位于1位和2位处 5. b被执行完成后,b自己的执行期上下文会被销毁,从而b函数会回归到b被定义的时刻 6. a被执行完成后,a自己的执行期上下文会被销毁,从而a函数会回归到a被定义的时刻,因为b函数 就位于a函数的函数体内,因此当a自己的执行期上下文被销毁的那一刻,b函数也会被永久销毁 7. 下一次开始,以此循环
|
③ 图解说明
a被定义时
a被执行时
b被定义时
b被执行时
b被执行完成后,会销毁自己的执行上下文,从而剪断作用域链上连接自己的执行上下文的那根线,回归至b被定义时的状态
a被执行完成后,会销毁自己的执行上下文,从而剪断作用域链上连接自己的执行上下文的那根线,回归至a被定义时的状态,但是,因为b函数在a函数的函数体内,所以b会被销毁掉
4.关于作用域与作用域链的其他代码说明
代码一 |
function a(){ function b(){ var b = 234; a = 0; //这个a是属于a函数自己的,位于a函数的AO上 } var a = 123; b(); console.log(a); //0 } var glob = 100; a();
|
代码二 |
function a(){ function b(){ var b = 234; var a = 0; //这个a是属于b函数自己的,是在他的函数体内定义的,位于b函数的AO上 console.log(a); //0 } var a = 123; b(); console.log(a); //123 } var glob = 100; a();
|
代码三 |
function a(){ function b(){ function c(){
} c(); } b(); } a();
|
代码三代码说明 |
a defined a.[[scope]] ----> 0:GO a doing a.[[scope]] ----> 0:aAO 1:GO
b defined b.[[scope]] ----> 0:aAO 1:GO b doing b.[[scope]] ----> 0:bAO 1:aAO 2:GO
c defined c.[[scope]] ----> 0:bAO 1:aAO 2:GO c doing c.[[scope]] ----> 0:cAO 1:bAO 2:aAO 3:GO
|
来源:https://www.cnblogs.com/080-hll/p/12380429.html