思考一下这两段代码的输出结果
Case 1:
1 | var up = 8; |
输出8还是88呢?
Case 2:1
2
3
4
5
6
7
8
9
10
11
12var up = 8;
function foo() {
up = 88
function bar() {
up = 888
console.log(up);
}
bar();
}
foo();
输出8, 88 还是888呢?
JavaScript是词法作用域
作用域: Scope
域表示的就是范围,即作业范围,具有访问权限的代码空间,作用域规定了如何查找变量,也就是确定当前执行代码对变量的访问权限。简单的讲就是在什么地方能使用,在什么不能使用。
词法作用域: Lexical Scope (Sometimes known as static scope)
词法作用域(通常也被叫做静态作用域)是代码在编写过程中就静态体现出来了作用范围,代码一旦写好,不用执行,他的作用范围就已经确定好了,这个就是所谓的词法作用域。
动态作用域: Dynamic Scope, 与词法作用域相反。
动态作用域并不关心函数和作用域是如何生命以及在何处声明的,之关心它们从何处调用。
回头分析下上面的两段代码
在Case1中,函数foo执行时,内部查找是否有变量up, 如果没有向上, 就根据书写的位置,查找上面一层的代码(也叫父变量对象,当然是词法结构上的),查找up = 8, 因此输出为8
在Case2中,函数bar执行,内部查找变量up, 就近原则,所以输出为888
全局作用域和函数作用域
JS的词法作用域有两种,一种是全局作用域,另外一种是函数作用域, 在函数作用域内会屏蔽在全局作用域上的相同名称的变量。
Reference:
Javascript’s lexical scope, hoisting and closures without mystery.