【JavaScript】【作用域】词法作用域和动态作用域

68 阅读2分钟

前言

  • 定义:作用域是指程序源代码中定义变量的区域

  • 作用:作用域规定了变量的使用范围,规定了如何查找变量,也就是确定当前执行代码对变量的访问权限

作用域分为词法作用域和动态作用域

一、词法作用域和动态作用域

1.1 词法作用域

词法作用域,又称静态作用域。

JavaScript的函数是词法上的作用域,而不是动态作用域。这意味着它们运行在自己定义的作用域,而不是运行在执行它们的作用域。也就是说在定义函数的时候,该函数的作用域就已经被决定了

1.2 动态作用域

动态作用域,与词法作用域相对的动态作用域,所以函数的作用域在函数调用的时候才决定的

举个栗子来看看词法作用域和动态作用域之间的区别:

var value = 1;

function foo() {
  console.log(value);
}

function bar() {
  var value = 2;
  foo();
}

直接执行foo()的结果:

image.png

直接执行bar()的结果:

image.png

很好,这两的的执行结果都是1,下面就让我们简单的分析分析。

首先,是我们的执行过程:

  • 假设采用静态作用域
    • 首先从 foo 函数内部查找是否有局部变量 value
    • 没有,就根据书写的位置,查找上面一层的代码
    • 发现value等于1,所结果会打印1
  • 假设采用动态作用域
    • 首先从 foo 函数内部查找是否有局部变量 value
    • 没有,就从调用函数的作用域,也就是 bar 函数内部查找 value 变量
    • 发现value等于2,所以结果会打印2

然后我们根据 bar 函数的实际执行结果,和上面两种假设情况,相互都可以证明:JavaScript函数的作用域是静态作用域

1.3 词法作用域与动态作用域的区别:

  • 动态作用域其实是 JavaScript 另一个重要机制 this 的表亲
  • 词法作用域是在书写代码或定义时确定的
  • 动态作用域是在运行时确定的。(this 也是)
  • 词法作用域关注函数在何处声明
  • 动态作用域关注函数从何处调用
  • 其实在 JavaScript 中的作用域大多为词法作用域。
  • 作用域链是基于调用栈的,而不是代码中的作用域嵌套的

拓展 什么语言会采用动态作用域呢?----- bash

参考