执行上下文
执行上下文有三种:
- 全局执行上下文
- 函数执行上下文
- eval 执行上下文
这里重点讲函数上下文
函数执行阶段可分为2个:函数建立阶段、函数执行阶段
函数建立阶段
当调用函数时,还未执行函数内部代码
创建执行上下文
ExecutionContext = {
variableObject, // 函数中的arguments、参数、局部变量 ,不可访问
scopeChains, // 当前函数所在的父级作用域中的活动对象
this // 当函数内部的this 指向
}
函数执行阶段
// 把变量对象转变为活动对象
ExecutionContext = {
activationObject, // 函数中的arguments、参数、局部变量, 可以访问
scopeChains, // 当前函数所在的父级作用域中的活动对象
this // 当函数内部的this 指向
}
比如:
function sub() {
function subInner() {
}
var s = 56;
}
在函数建立阶段 activationObject: {subInner: 函数内存地址,s: undefined }
看一个函数的打印
function fn(a, b) {
function inner() {
console.log(a, b);
}
console.dir(inner);
// return inner;
}
console.dir(fn);
const f = fn(1, 2);
通过var 定义的变量都会存储到 Global 中,通过let、const 定义的变量会到Script 中。
通过打印可知,闭包是函数定义时就存在,不是函数执行时才存在。
闭包
function makeFn() {
let name = "MDN"
return function inner() {
console.log(name)
}
}
let fn = makeFn();
fn();
闭包发生的两个必要条件:
- 外部对一个函数makeFn内部有引用
- 在另一个作用域能够访问到 makeFn 作用域内部的局部成员。
使用闭包可以突破变量作用域的限制,原来只能从一个作用域访问外部作用域的成员,有了闭包之后,可以在外部作用域访问一个内部作用域的成员
可以缓存参数
根据不同参数生成不同功能的函数