执行上下文(execution context)
- 函数执行时,会创建一个称为执行上下文的环境,分为创建和执行两个阶段。
创建阶段
- 创建一个拥有3个属性的excutionContext对象
executionContext = {
scopeChain: {}, // 创建作⽤域链(scope chain)
variableObject: {}, // 初始化变量、函数、形参
this: {} // 指定this
}
执行阶段
-
- 分配变量、函数引用、赋值
-
- 执行代码
AO
AO步骤:
- 创建AO(Activation Object)对象,又叫执行期上下文;
- 寻找形式参数和变量声明作为AO的属性名,并赋值为undefined;
- 传入实际参数的值;
- 在函数体内寻找函数声明,放入作为AO的属性,并赋值为其函数体。
GO
GO步骤:
- 创建GO(Global Object)对象;
- 寻找变量声明作为GO的属性名,并赋值为undefined;
- 寻找函数声明,放入作为GO的属性,并赋值为其函数体。
执行上下文栈
- 一个
全局执行上下文
和多个函数执行上下文
=== 执行上下文栈
作用域
- js中有全局作用域、函数作用域、es6新增块级作用域
- 隔离函数或者变量
- 作用域在执行上下文创建时定义
作用域链
- 函数嵌套另一个函数,发生作用域嵌套
- js引擎在当前函数中无法找到某个变量,就会往上一级嵌套的作用域中寻找,直到找到该变量或者抵达全局作用域
- 这样的链式关系被称为
作用域链
闭包
- 有权访问 另一个函数作用域中变量的函数(能够读取其他函数内部变量的函数)
- 私有性体现在:创建多个实例,互不影响(多个实例数据独立性);延长变量生命周期体现在,同一个实例对象下闭包函数访问的变量不销毁,防抖和节流应用(单个实例数据持久性)
- 封装私有属性,私有环境互不干扰
// ⼯⼚⽅法
function Person() {
// 外部无法访问,私有
var _attackVolume = 100;
function attack(val){
_attackVolume += val
}
return {
add:function(){
attack(1)
},
reduce:function(){
attack(-1)
},
value:function(){
return _attackVolume
}
};
}
// 拥有各自的词法环境
var person = new Person();
var person2 = new Person()
person.add()
console.log(person.value()) // 101
console.log(person2.value()) // 100
person.add()
// 延长变量生命周期
console.log(person.value()) // 102
- 存储变量,延长变量生命周期
/ 封装的时候
function getListDataManager() {
// 外层scope中定义⼀个变量
let localData = null;
return {
getData() {
// ⾥⾯的函数使⽤外层的变量,⽽且是反复使⽤
if (localData) {
return Promise.resolve(localData);
}
return fetch('xxxx')
.then(data => localData = data.json());
}
};
}
// ⽤的时候
const listDataManager = getListDataManager();
//listDataManager 接收闭包函数,localData不会销毁
button.onclick = () => {
// 每次都会去获取数据,但是有可能是获取的缓存的数据
text.innerHTML = listDataManager.getData();
};
window.onscroll = () => {
// 每次都会去获取数据,但是有可能是获取的缓存的数据
text.innerHTML = listDataManager.getData();
};
this
1、对于直接调⽤的函数来说,不管函数被放在了什么地⽅,this都是window
2、对于被别⼈调⽤的函数来说,被谁点出来的,this就是谁
3、在构造函数中,类中(函数体中)出现的this.xxx=xxx中的this是当前类的⼀个实例
4、call、apply时,this是第⼀个参数。bind要优与call/apply哦,call参数多,apply参数少
5、箭头函数没有⾃⼰的this,需要看其外层的是否有函数,如果有,外层函数的this就是内部箭头函数
的this,如果没有,则this是window