作用域
- js 采用的是静态作用域,所以函数的作用域在函数定义时就确定了,并且不会改变。
var value = 1;
function foo() {
console.log(value);
}
function bar() {
var value = 2;
foo();
}
bar();
// 打印 1
var scope = "global scope";
function checkscope(){
var scope = "local scope";
function f(){
return scope;
}
return f();
}
checkscope();
// 打印 local scope
var scope = "global scope";
function checkscope(){
var scope = "local scope";
function f(){
return scope;
}
return f;
}
checkscope()();
// 打印 local scope
执行上下文
-
执行上下文在运行时确定,随时可能改变。
-
执行上下文后才执行代码。
-
在进入执行上下文时,首先会处理函数声明,其次会处理变量声明,如果变量名称跟已经声明的形式参数或函数相同,则变量声明不会干扰已经存在的这类属性。
全局上下文
-
变量对象(Variable object,VO)是与执行上下文相关的数据作用域,存储了在上下文中定义的变量和函数声明。
-
全局上下文中的变量对象就是全局对象(如window(不同环境不同))
// 执行上下文后的变量对象
// window = {
// ...window,
// a: undefined
// }
var a = 1
b = 2 // 到这边变量对象添加 b: 2
console.log(window.a) // 打印1
console.log(window.b) // 打印2
// 执行上下文后的变量对象
// window = {
// ...window,
// a: function () {}
// }
console.log(a); // 打印函数
function a() {}
var a = 1
函数上下文
-
在函数上下文中,用活动对象(activation object, AO)来表示变量对象。
-
活动对象是在进入函数上下文时刻被创建的,它通过函数的 arguments 属性初始化。arguments 属性值是 Arguments 对象。
// 执行函数上下文后的变量对象
// VO = {
// arguments: {
// 0: 1,
// length: 1
// },
// a: 1,
// b: undefined
// }
function a(a) {
console.log(a); // 打印1
var a = 2
var b = 3
}
a(1)
// 执行函数上下文后的变量对象
// VO = {
// arguments: {
// length: 0
// },
// }
function foo() {
console.log(a); // 由变量对象拿不到,在这直接报错 a is not defined
a = 1;
}
foo();