作用域:
1:作用域是指程序代码定义变量得区域。
2:作用域规定如何查找变量,也就确定当前执行代码对变量得访问权限,或者说,当前执行代码使用变量赋值
3:js 中采用得静态作用域。静态作用域 与执行环境无关与声明有关
作用域得分类: 全局和局部
1:全局相当于浏览器,window 对象下所用内容都是全局得,访问权限 再任意代码中
2:局部作用域:函数方法体内部声明变量,访问权限再方法体内部
var value = 1;
function foo() {
console.log(value);
}
function bar() {
var value = 2;
foo();
}
bar();
// 结果是 ???
分析执行过程
一:静态作用域 :执行 foo函数,先从foo函数内部查找是否有局部变量 value 如果没有就根据书写得位置,查找上面一层得代码 也就是 value 等于1 所以结果会打印1。
二:动态作用域:执行 foo 函数,依然是从 foo 函数内部查找是否有局部变量 value。如果没有,就从调用函数的作用域,也就是 bar 函数内部查找 value 变量,所以结果会打印 2。
作用域链:
当查找变量得时候,会先从当前上下文得变量对象中查找,如果没有就从父级执行上下文得变量对象中查找,一直找到全局上下文得变量对象,也就是全局对象, 这样由多个执行上下文得变量对象构成得链表结构 叫做作用域链
函数创建
当函数创建得时候,就会保存所有父变量对象到[[scope]]中,你可以理解[[scope·]] 就是父变量得层级链 但是[[scope]] 不代表完整得作用域链
例子:
function foo() {
function bar() {
...
}
创建函数时:各自得[[scope]] 为:
foo.[[scope]] = [
globalContext.VO
];
bar.[[scope]] = [
fooContext.AO,
globalContext.VO
];
函数激活:
当函数激活时,进入函数上下文,创建VO/AO后,就会将活动对象添加到作用域链得前端。
这时候执行上下文得作用域链,我们命名为 scope;
Scope = [AO].concat([[Scope]]);
现在,作用域创建完毕