作用域和作用域链的理解

时间:2025-01-18 22:44:08
作用域(scope)
1. 什么是作用域

作用域是在运行代码中某些特定部分中变量、函数和对象的可访问性。也就是说,作用域决定了代码区块中变量和其他的可访问性。
ES6之前JavaScript没有块级作用域,只有全局作用域和局部作用域。ES6的到来,为我们提供了块级作用域,可通过命令let和const来体现。

  • 所有未定义直接赋值的变量自动声明为全局变量
2. 什么是作用域链

如果想得到在当前的作用域里没有定义的变量(即*变量)的值,需要向父级作用域(下文有解释)寻找,如果父级没有,会接着向上寻找,如果直到在全局作用域里没有找到,就宣布放弃。这种一层层的关系,就是作用域链。

3. *变量取值的理解

无论fn函数在哪里调用,都要到创建fn这个函数的哪个作用域(即静态作用域)里取值。

var a = 10
function fn() {
  var b = 20
  function bar() {
    console.log(a + b)
  }
  return bar
}
var x = fn(),
  b = 200
x() //30

原因是JavaScript是解释型语言,他的执行分为解释和执行两个阶段:

解释阶段:

  • 词法分析
  • 语法分析
  • 作用域规则确定

执行阶段:

  • 创建执行上下文
  • 执行函数代码
  • 垃圾回收

也就是说:

  • 作用域在函数定义的时候就确定的,不会改变。
  • 执行上下文时this的指向是执行时确定的,可随时改变。