JS-作用域链

什么是作用域链?

当代码在一个环境中执行时,都会创建一个作用域链。 作用域链的用途是保证对执行环境有权访问的所有变量和函数的有序访问。整个作用域链的本质是一个指向变量对象的指针列表。作用域链的最前端,始终是当前正在执行的代码所在环境的变量对象。
  如果这个环境是函数,则将其活动对象(activation object)作为变量对象。活动对象在最开始时只包含一个变量,就是函数内部的arguments对象。作用域链中的下一个变量对象来自该函数的包含环境,而再下一个变量对象来自再下一个包含环境。这样,一直延续到全局执行环境,全局执行环境的变量对象始终是作用域链中的最后一个对象。

3个概念

  • 执行上下文sexecutionContext(或者叫全局作用域global context)
  • 活动对象 AO:当前执行环境中声明的变量和函数
  • Scope 属性:作用域链

范例1

1.var x = 10

2.bar()

function foo() {
  console.log(x)
}
function bar(){
  var x = 30
  3.foo() //  输出什么
}
1.
globalContext = {
    AO: {
        x:10
        foo:function
        bar:function
    },
    scope:null
}
//声明 foo 时 得到下面
foo.[[scope]] = globalContext.AO
//声明 bar 时 得到下面
bar.[[scope]] = globalContext.AO

注意: 在当前的执行上下文内声明的函数,这个函数的[[scope]]就执行当前执行上下文的 AO(活动对象)

2.
当调用 bar() 时, 进入 bar 的执行上下文

barContext = {
  AO: {
    x: 30
  },
  Scope: bar.[[scope]] //globalContext.AO  
  //当bar中调用 foo() 时,先从 bar 执行上下文中的 AO里找,找不到再从 bar 的 [[scope]]里找 找到后即调用
}

3.
当调用 foo() 时,进入 foo 的执行上下文

fooContext = {
  AO: {},
  Scope: foo.[[scope]] // globalContext.AO
}

所以 console.log(x)是 10

范例2

var x = 10;
bar() //  输出什么
function bar(){
  var x = 30;
  function foo(){
    console.log(x)
  }
  foo();
}
1.globalContext = {
  AO: {
    x: 10
    bar: function
  },
  Scope: null
}
bar.[[scope]] = globalContext.AO
注意: 在当前的执行上下文内声明的函数,这个函数的[[scope]]就执行当前执行上下文的 AO

2.当调用 bar() 时, 进入 bar 的执行上下文

barContext = {
  AO: {
    x: 30,
    foo: function
  },
  Scope: bar.[[scope]] //globalContext.AO
}
//在 bar 的执行上下文里声明 foo 时 得到下面
foo.[[scope]] = barContext.AO

3.
当调用 foo() 时,先从 bar 执行上下文中的 AO里找,找到后即调用
当调用 foo() 时,进入 foo 的执行上下文
fooContext = {
  AO: {},
  Scope: foo.[[scope]] // barContext.AO
}
所以 console.log(x)是 30
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 给出两个不同的例子: 范例1: 分析上面代码:全局作用域中定义了变量x,function foo()以及funct...
    DeeJay_Y阅读 2,642评论 0 1
  • 函数声明和函数表达式有什么区别? 1.声明的函数foo将会在执行前提升,因此foo在函数上下文都是可以被调用的,即...
    小囧兔阅读 2,325评论 0 1
  • 之前写过一篇JavaScript 闭包究竟是什么的文章理解闭包,觉得写得很清晰,可以简单理解闭包产生原因,但看评论...
    宁骥阅读 2,675评论 0 1
  • 作用域:定义这个变量的区域 作用域链:当前活动对象,加上包含它的所有活动对象 作用域链的作用:是保证执行环境里有权...
    07120665a058阅读 1,716评论 0 0
  • 17年6月18日 唐河百里画廊位于河北省唐县境内,从保定出发上保涞路直走不到80公里即到.唐河发源于山西省灵邱县高...
    八道I江山阅读 5,101评论 0 2