JavaScript 作用域链(Scope Chain)是什么?有什么作用?

结论先行:

当在函数内部访问一个变量的时候,(JS 引擎)程序会先在当前作用域中查找(是否存在该变量),如果找到了就直接使用。否则就会向上层作用域逐级查找,直到找到全局作用域为止。这个查找过程形成了作用域链。

在函数中定义的变量也可以被嵌套在其他函数的作用域中,这样就形成了作用域链。

它保证了变量在正确的作用域中被访问和使用。 

作用域链呢,有2个作用。一个就是刚说的变量查找,再一个就是闭包实现,通过作用域链,内部函数可以访问外部函数的变量,从而实现闭包。

  • 变量查找:当在函数内部引用一个变量时,JavaScript 引擎会在当前函数的作用域中查找该变量,如果找不到,则会沿着作用域链向上查找,直到找到全局作用域。
  • 闭包实现:通过作用域链,内部函数可以访问外部函数的变量,从而实现闭包(Closure),使得外部函数的作用域在内部函数执行完毕后仍然可以被引用。

具体解析:

1、什么是作用域链(Scope Chain)? 

在JavaScript中,函数存在一个隐式属性 [[ scopes ]],这个属性用来保存当前函数在执行时的环境(上下文),由于在数据结构上是链式的,也称为作用域链。我们可以把它理解为一个数组。

function fn() {}
console.dir(fn) // 打印内部结构

2、作用域的内部结构

内部结构如下: 

scopes 属性在函数声明时产生,在函数被调用时更新,记录当前函数的执行环境。

在函数被调用时,将该函数的AO对象压入到[[ scopes ]]

JavaScript 作用域链(Scope Chain)是什么?有什么作用?_第1张图片

JavaScript 作用域链(Scope Chain)是什么?有什么作用?_第2张图片

梳理作用域链:

function a() {
  console.dir(a)
  function b() {
    console.dir(b)
    function c() {
      console.dir(c)
    }
    c()
  }
  b()
}
a()

调试和打印结果如下:

 JavaScript 作用域链(Scope Chain)是什么?有什么作用?_第3张图片

 JavaScript 作用域链(Scope Chain)是什么?有什么作用?_第4张图片

3、作用域链的作用

在访问变量或者函数的时候,会在作用域链上依次查找。先查找自己的AO是否存在变量和函数,不存在的话,再一层一层向上查找,直到找到GO;

外层的函数无法访问内部函数的变量;而内部函数可以访问外部函数的变量。

 JavaScript 作用域链(Scope Chain)是什么?有什么作用?_第5张图片       JavaScript 作用域链(Scope Chain)是什么?有什么作用?_第6张图片

第一个例子的aa打印的是 111

第二个例子的aa打印的是 222

4、总结

作用域链的形成是由函数创建时确定的,它由函数创建时所处的执行上下文(Execution Context)和它的词法环境(Lexical Environment)组成。

作用域链的作用包括:

  • 变量查找:当在函数内部引用一个变量时,JavaScript 引擎会在当前函数的作用域中查找该变量,如果找不到,则会沿着作用域链向上查找,直到找到全局作用域。
  • 闭包实现:通过作用域链,内部函数可以访问外部函数的变量,从而实现闭包(Closure),使得外部函数的作用域在内部函数执行完毕后仍然可以被引用。

作用域链的形成是 JavaScript 语言实现词法作用域(Lexical Scope)的重要基础,它保证了函数内部对外部作用域的可访问性,并且决定了变量在程序中的可见范围和生命周期。

通过作用域链,JavaScript 实现了变量的作用域和闭包特性,使得代码具有更好的封装性和灵活性。

你可能感兴趣的:(每日专栏,JavaScript,javascript,前端)