这是我参与8月更文挑战的第6天,活动详情查看:8月更文挑战markdown
函数定义
的时候就决定了函数调用
的时候才决定的看以下例子:app
let a = 2;
function foo() {
console.log(a); // 会输出2仍是3?
}
function bar() {
let a = 3;
foo();
}
bar()
复制代码
假设 JavaScript 采用词法做用域(也可称为静态做用域),让咱们分析下执行过程:ide
执行 foo 函数,先从 foo 函数内部查找是否有局部变量 a,若是没有,就根据书写的位置,查找上面一层的代码,也就是 a 等于 2,因此结果会打印 2。函数
假设 JavaScript 采用动态做用域,让咱们分析下执行过程:post
执行 foo 函数,依然是从 foo 函数内部查找是否有局部变量 a。若是没有,就从调用函数的做用域,也就是 bar 函数内部查找 a 变量,因此结果会打印 3。ui
前面咱们已经说了,JavaScript 采用的是词法做用域,因此这个例子的结果是 2。this
词法做用域是写代码的时候就静态肯定下来的;而动态做用域并不关心函数和做用域是如何声明以及在何处声明的,只关心它们从何处调用。换句话说,做用域链是基于调用栈的,而不是代码中的做用域嵌套。lua
Javascript 并不具备动态做用域,它只有词法做用域,简单明了。可是,它的 eval()、with、this 机制某种程度上很像动态做用域,使用上要特别注意。url
词法做用域是在写代码或者定义时肯定的,而动态做用域是在运行时肯定的(this也是!)。词法做用域关注函数在何处声明,而动态做用域关注函数从何处调用。spa
- this 相似动态做用域
- JavaScript 执行是静态做用域