有关作用域链,执行上下文,闭包原理
作用域说明:变量的作用范围
全局作用域
- 全局作用域在页面打开时被创建,页面关闭时被销毁
- 编写在script标签中的变量和函数,作用域为全局,在页面的任意位置都可以访问到
- 在全局作用域中有全局对象window,代表一个浏览器窗口,由浏览器创建,可以直接调用
- 全局作用域中声明的变量和函数会作为window对象的属性和方法保存
函数作用域
- 调用函数时,函数作用域被创建,函数执行完毕,函数作用域被销毁
- 每调用一次函数就会创建一个新的函数作用域,他们之间是相互独立的
- 在函数作用域中可以向上访问到上级作用域的变量,上级作用域无法访问到函数作用域内的变量
- 在函数作用域中访问变量,函数时,会先在自身作用域中寻找,若没有找到,则会函数的上一级作用域中寻找一直到全局作用域
作用域的深层次理解
更为准确的叫执行上下文
变量对象 (Variable Object)VO:存储了在上下文中定义的变量和函数声明;除了我们无法访问它外,和普通对象没什么区别。供js引擎自己去访问 我们是访问不到的 但是它是的确存在的
对于函数,执行前的初始化阶段叫变量对象,执行中就变成了活动对象。AO
每一个执行环境都有一个与之相关的变量对象,其中存储着上下文中声明的:
变量
函数
形式参数
全局作用域的预编译
- 创建 VO对象
- 找变量声明 将变量名作为GO对象的属性名 值是undefined
- 找函数声明 值赋予函数体
函数作用域预编译
- 创建ao对象 AO{}
- 找形参和变量声明 将变量和形参名 当做 AO对象的属性名 值为undefined
- 实参形参相统一
- 在函数体里面找函数声明 值赋予函数体
作用域链
- 会被保存到一个隐式的属性中去 [[scope]] 这个属性是我们用户访问不到的 但是的的确确是存在的 让js引擎来访问的 里面存储的就是作用域链 AO VO AO 和 VO的集合
分析闭包
var global
function a() {
// 到这个里面来了
var aa = 123
// b函数定义
function b() {
// 到这里面来了
var bb = 234
aa = 0
}
// b执行
b()
console.log(aa);
}
// a执行
a()