CLAYYA

乌贼馋辣鱼的博客

词法作用域和动态作用域

2024-11-26

词法作用域和动态作用域

作用域

作用域是确定在何处以及如何查找变量的一套规则。JavaScript 采用词法作用域(lexical scoping),也就是静态作用域。

词法作用域与动态作用域

词法作用域:因为 JavaScript 采用的是词法作用域,函数的作用域在函数定义的时候就决定了。函数的作用域基于函数创建的位置。

动态作用域:而与词法作用域相对的是动态作用域,函数的作用域是在函数调用的时候才决定的。

闭包与作用域

闭包是指一个函数能够访问其定义时的作用域中的变量,即使在其定义的作用域已经执行完毕后。这意味着闭包可以让函数“记住”它被创建时的环境,即使它在另一个环境被调用,而这种“记住”正是通过作用域链实现。

在 JavaScript 中,外部函数无法直接访问内部函数的变量,这是由于作用域链的单向性决定的。当函数嵌套时,内部函数可以访问外部函数的变量(包括参数、局部变量和外部函数的内部函数的变量),但外部函数不能访问内部函数的变量。这是因为内部函数的作用域链包含了外部函数的作用域,而外部函数的作用域链中并不包含内部函数的作用域。因此,内部函数可以访问外部函数的变量,但外部函数不能访问内部函数的变量。

尽管外部函数不能直接访问内部函数的变量,但可以通过返回内部函数来创建闭包,从而间接访问这些变量。闭包使得内部函数即使在其外部函数执行完毕后,仍然可以访问外部函数的作用域中的变量。 使内部函数返回一个函数形成闭包,通过闭包,外部函数可操作内部变量。这样做的话一是可以读取函数内部的变量,二是可以让这些变量的值始终保存在内存中。

每个函数都有自己的作用域和作用域链,当函数执行时,会创建一个执行上下文(execution context),其中包括一个作用域链。作用域链包含了函数的局部变量、父函数的变量,以及全局变量。 闭包因为保留了这个作用域链,所以可以访问定义这个闭包函数时,它所在位置的外部函数的变量(词法作用域)。