前言
-
定义:作用域是指程序源代码中定义变量的区域
-
作用:作用域规定了变量的使用范围,规定了如何查找变量,也就是确定当前执行代码对变量的访问权限
作用域分为词法作用域和动态作用域
一、词法作用域和动态作用域
1.1 词法作用域
词法作用域,又称静态作用域。
JavaScript的函数是词法上的作用域,而不是动态作用域。这意味着它们运行在自己定义的作用域,而不是运行在执行它们的作用域。也就是说在定义函数的时候,该函数的作用域就已经被决定了
1.2 动态作用域
动态作用域,与词法作用域相对的动态作用域,所以函数的作用域在函数调用的时候才决定的
举个栗子来看看词法作用域和动态作用域之间的区别:
var value = 1;
function foo() {
console.log(value);
}
function bar() {
var value = 2;
foo();
}
直接执行foo()的结果:
直接执行bar()的结果:
很好,这两的的执行结果都是1,下面就让我们简单的分析分析。
首先,是我们的执行过程:
- 假设采用静态作用域:
- 首先从 foo 函数内部查找是否有局部变量 value
- 没有,就根据书写的位置,查找上面一层的代码
- 发现value等于1,所结果会打印1
- 假设采用动态作用域:
- 首先从 foo 函数内部查找是否有局部变量 value
- 没有,就从调用函数的作用域,也就是 bar 函数内部查找 value 变量
- 发现value等于2,所以结果会打印2
然后我们根据 bar 函数的实际执行结果,和上面两种假设情况,相互都可以证明:JavaScript函数的作用域是静态作用域
1.3 词法作用域与动态作用域的区别:
- 动态作用域其实是 JavaScript 另一个重要机制 this 的表亲
- 词法作用域是在书写代码或定义时确定的
- 动态作用域是在运行时确定的。(this 也是)
- 词法作用域关注函数在何处声明
- 动态作用域关注函数从何处调用
- 其实在 JavaScript 中的作用域大多为词法作用域。
- 作用域链是基于调用栈的,而不是代码中的作用域嵌套的
拓展 什么语言会采用动态作用域呢?----- bash