简析作用域链

执行环境

执行环境,也称环境,其中定义了变量或函数有权访问的其他数据,每个执行环境都有一个与之相关的变量对象,环境中定义的全部变量,函数都保存在其中。当某个执行环境中的代码全都执行完毕,该环境的占用的内存就会被释放,环境就会销毁,保存在其中的变量函数也全都销毁。
全局执行环境是指所有环境中最外围的环境,在web浏览器里,一般全局环境被默认为是window对象。
每个函数都有自己的执行环境,当代码执行到一个函数时,这个函数的环境就会被置入一个环境栈中,而当函数执行完毕之后,其环境也从栈中移除,重新变为之前的执行环境。

作用域链

当代码在一个环境中执行时,会创建变量的一个作用域链。作用域的作用就是保证对执行环境中的变量和函数的有序访问。
作用域的最前端就是当前执行的代码所在的环境的变量对象,下一个变量就是上一层的变量对象,也就是包含环境,依此类推,最后端始终是全局执行环境的变量对象。

 var a = 1;
 function fn(){
    var b = 2;
    function fn1(){
      var c = 3;
   }
 }

最前端的变量对象就是我们函数fn1()所在环境的变量对象包含了变量c;
再上一层就是函数fn()所在环境的变量对象,包括变量c以及函数fn1(),再向上一层就是我们的最外层,全局环境变量,包括变量a,和函数fn()

简析作用域链_第1张图片
手画的,比较丑。。。作用域链并不是像图上所画的一条线,一个变量或一个函数就是一个作用域,而是一块一块的,这是也为什么我先说明后画图的原因

我们的标识符解析就是沿着作用域链,从最前端一级一级的向上搜索标志符,知道找到标识符的过程。(如果找不到通常会报错)

 var a = 1
 function fn1(){
  function fn2(){
    console.log(a)
  }
  function fn3(){
    var a = 4
    fn2()
  }
  var a = 2
  return fn3
}
var fn = fn1()
    fn() //输出多少

执行fn,也就是fn1(),return fn3我们看看fn3()又实现了什么,fn2(),调用fn2()函数,console.log(a);但是fn2()里没有定义变量a啊,我们就沿着作用域链向上找,fn2()定义在fn1()下面,上一层作用域就是fn2()+变量a+fn3(),我们发现这里定义了变量a,并且赋值为2,所以打印结果为2

函数在执行的过程中,先从自己内部找变量
如果找不到,再从创建当前函数所在的作用域去找, 以此往上
注意找的是变量的当前的状态

在作用域链中,内部环境可以同过作用域链访问所有的外部环境,但外部环境不闹访问内部环境中的任何变量和函数。即每个环境都可以向上搜索作用域链,以查询比拿两盒函数,但不能向下搜索作用域链,从而进入另一个执行环境。这也就是外部不能访问函数内部变量的原因

你可能感兴趣的:(简析作用域链)