一、作用域
- 作用域是指程序源代码中定义变量的区域
- 作用域规定了如何查找变量,也就是确定当前执行代码对变量的访问权限
JavaScript采用的是词法作用域 (lexical scoping) ,也就是静态作用域
二、词法作用域(静态作用域)
词法作用域也就是在词法阶段定义的作用域,也就是说词法作用域在代码书写时就已经确定了
- 因为 JavaScript 采用的是词法作用域,函数的作用域在函数定义的时候就决定了。而与词法作用域相对的是动态作用域,函数的作用域是在函数调用的时候才决定的
- JavaScript 中其实只有词法作用域,并没有动态作用域,this 的执行机制让作用域表现的像动态作用域,this 的绑定是在代码执行的时候确定的 ```javascript // 词法作用域 var value = 1; function foo() { console.log(value); } function bar() { var value = 2; foo(); }
bar(); // 1 // 函数在哪里调用没有关系,变量的位置在编译的词法分析阶段就确定了。
代码分析:执行foo函数,首先在它的内部作用域查找是否有value这个局部变量,如果有就会使用这个局部变量,如果没有,根据书写的代码就会向上一层寻找,这时发现value变量存在是1,这就是词法作用域
<a name="vtlcp"></a>
# 三、动态作用域
- 动态作用域的变量叫做动态变量。只要程序正在执行定义了动态变量的代码段,那么在这段时间内,该变量一直存在;代码段执行结束,该变量便消失。
```javascript
// 动态作用域
var value = 1;
function foo() {
console.log(value);
}
function bar() {
var value = 2;
foo();
}
bar(); // 2
代码分析:执行 foo 函数,依然是从 foo 函数内部查找是否有局部变量 value。如果没有,就从调用函数的作用域,也就是 bar 函数内部查找 value 变量,所以结果会打印 2,这就是动态作用域
四、思考题
- 《JavaScript权威指南》中的例子
var scope = "global scope";
function checkscope(){
var scope = "local scope";
function f(){
return scope;
}
return f();
}
checkscope();
答案分析 :两段代码都会打印:local scope。原因也很简单,因为JavaScript采用的是词法作用域,函数的作用域基于函数创建的位置var scope = "global scope";
function checkscope(){
var scope = "local scope";
function f(){
return scope;
}
return f;
}
checkscope()();
《JavaScript权威指南》答案:JavaScript 函数的执行用到了作用域链,这个作用域链是在函数定义的时候创建的。嵌套的函数 f() 定义在这个作用域链里,其中的变量 scope 一定是局部变量,不管何时何地执行函数 f(),这种绑定在执行 f() 时依然有效