学习笔记——JavaScript作用域链

听小野森森的作用域链,收获颇丰。

函数在声明的时候会创建一个js内部的隐式属性,[[scope]],保存当前的作用域链,默认第一位是GO。

函数在执行的时候会创建自己的AO,保存在作用域链的第一位,之前保存的作用域往后排。

函数执行完毕后,会销毁自己AO,如果这个AO还保存在别的函数的作用域中,则不会被销毁。

函数再次执行,会重新创建AO。

function a() {
  function b() {
    var b = 2;
  }
  var a = 1;
  b();
}

var c = 3;
a();

当程序执行时,a函数被定义,系统为起生成[[scope]]属性,[[scope]]保存该函数的作用域链,该作用域链的第0位保存当前环境下的全局上下文GO,GO里存储全局下的所有对象,其中包含函数 a 和全局变量 c 。

学习笔记——JavaScript作用域链_第1张图片

  • 函数执行的前一刻

学习笔记——JavaScript作用域链_第2张图片

b函数被定义

学习笔记——JavaScript作用域链_第3张图片

b函数被执行

学习笔记——JavaScript作用域链_第4张图片

b函数执行结束时

学习笔记——JavaScript作用域链_第5张图片

a函数执行结束时

学习笔记——JavaScript作用域链_第6张图片

学习笔记——JavaScript作用域链_第7张图片

练习

function a() {
  function b() {
    function c() {
    }
    c();
  }
  b();
}
a();


// a定义 a.[[scope]] -> 0 : G0
// a执行 a.[[scope]] -> 0 : a-A0  1 : G0
// b定义 b.[[scope]] -> 0: a-A0   1: G0
// b执行 b.[[scope]] -> 0: b-A0   1: a-A0  2:G0
// c定义 c.[[scope]] -> 0: b-A0   1: a-A0  2:G0
// c执行 c.[[scope]] -> 0: c-A0   1: b-A0  2: a-A0 3:GO
// c执行完 c.[[scope]] -> 0: b-AO  1: a-AO 2:GO
// b执行完 b.[[scope]] -> 0: a-A0  1:G0
//                       c.[[scope]] X
// a执行完 a.[[scope]] -> 0:G0
//       b.[[scope]] X

闭包

function test1() {
      function test2() {
            var b = 2;
            console.log(a);
      }
      var a = 1;
      return test2;
}

var c = 3;
var test3 = test1();

test();

学习笔记——JavaScript作用域链_第8张图片

学习笔记——JavaScript作用域链_第9张图片

学习笔记——JavaScript作用域链_第10张图片

学习笔记——JavaScript作用域链_第11张图片

学习笔记——JavaScript作用域链_第12张图片

你可能感兴趣的:(javascript)