什么是作用域?
作用域是一套规则,用于确定在何处以及如何查找变量(标识符)。也就是确定当前执行代码对变量的访问权限。
- LHS和RHS对变量两种查找操作
字面意思,left hand side right hand side, 是一个赋值操作的左侧和右侧。 如果查找的目的是对变量进行赋值,那么就会使用 LHS 查询;
- lhs var a = 2; 不管 = 2 赋给谁,只想找到一个容器赋值 如果目的是获取变量的值,就会使用 RHS 查询。 rhs retrieve his source value 取到它的源值
- console.log(a),a就是rhs引用,并没有赋予任何值,只是找到它
function foo(a) {
var b = a;
return a + b;
}
var c = foo( 2 );
- 找出所有的 LHS 查询 (这里有 3 处!)c = ..;、a = 2(隐式变量分配)、b = ..
- 找出所有的 RHS 查询 (这里有 4 处!) foo(2..、= a;、a ..、.. b
静态作用域?
由写代码期间函数所声明的位置来定义
var value = 1;
function foo() {
console.log(value);
}
function bar() {
var value = 2;
foo();
}
bar();
// 结果是 ??? 执行 foo 函数,先从 foo 函数内部查找是否有局部变量 value,如果没有,就根据书写的位置,查找上面一层的代码,也就是 value 等于 1,所以结果会打印 1。
动态作用域?
函数的作用域是在函数调用的时候才决定的
- 假设JavaScript采用动态作用域,让我们分析下执行过程: 执行 foo 函数,依然是从 foo 函数内部查找是否有局部变量 value。如果没有,就从调用函数的作用域,也就是 bar 函数内部查找 value 变量,所以结果会打印 2。
var scope = "global scope";
function checkscope(){
var scope = "local scope";
function f(){
return scope;
}
return f();
}
checkscope();
var scope = "global scope";
function checkscope(){
var scope = "local scope";
function f(){
return scope;
}
return f;
}
checkscope()();
因为JavaScript采用的是词法作用域,函数的作用域基于函数创建的位置。
结果都是“local scope”
但是这两个也是有区别的,当函数执行完毕的时候,就会将函数的执行上下文从栈中弹出
- 第一个是先checkscope压栈,在f压栈,然后再弹栈
- 第二个checkscope压栈,执行完,弹栈,再f压栈,然后再弹栈