知识点:全局上下文、函数上下文;执行上下文、执行上下文栈
浏览器在打开一个标签页的时候会创建唯一的全局上下文,只有在关闭浏览器窗口的时候才会被释放,把执行上下文栈看作羽毛球桶的话,全局上下文就是放进桶里的第一个羽毛球。
这里需要放对应的图,正在学画
在执行JS代码前,代码先经历创建阶段,这个阶段做的工作就是创建执行上下文
注意全局上下文和全局上下文scope不是同一个东西,var和function是创建在全局上下文中(相当于window),let、const、class则创建在全局scope。浏览器在新建tab标签页面的时候创建了全局上下文,在初始化一个js文件前创建了全局的scope。
全局执行上下文和全局scope
// 下面的代码很好的证明了全局上下文不是全局scope上下文
// var
var _var = '我是var'
console.log(_var) // 我是var
console.log(window._var) // 我是var
// function
function _fun(){
console.log('我是function')
}
_fun() // 我是function
window._fun() // 我是function
// let
let _let = '我是let'
console.log(_let) // 我是let
console.log(window._let) // undefined
// const
const _const = '我是const'
console.log(_const) // 我是const
console.log(window._const) // undefined
// class
class _class{
constructor(){
return '我是calss'
}
say(){
console.log('我是calss')
}
}
每个执行上下文都包含:变量对象、作用域链、this
function person(){
var age = 20
functon sayHello(){
console.log('我是小布')
}
}
{
/* 作用域链
可理解作用域链就是变量对象的数组;
数组第一位scopeChain[0]就是当前执行上下文的VO
*/
scopeChain: [],
/* 变量对象
variableObject = VO(简称)
arguments, 函数参数, 内部变量 等等
*/
variableObject: {
arguments: {}, // 函数执行上下文的参数对象
sayHello: {}, // 函数声明
age: 20
},
/*this指向当前执行上下文的vo*/
this: {}
}
stateDiagram-v2
执行上下文1 --> 变量对象(VO)
执行上下文1 --> 作用域链
作用域链 --> 作用域链第一个
执行上下文1 --> this
this --> 变量对象(VO)
变量对象(VO) --> arguments
变量对象(VO) --> sayHello
变量对象(VO) --> age
变量对象(VO) --> 作用域链第一个
作用域链第一个 --> 变量对象(VO)
示例:变量对象VO在执行上下文创建和执行过程中的变化
function person(args){
// 变量
var age = '22'
// 函数声明
function personAge(){
return age
}
return personAge
}
person('王小明')
// 创建阶段
VO = {
arguments: {
0: '王小明',
length: 1
},
age: undefined,
personAge: '局部函数执行上下文' // pointer to function f()
}
// 执行阶段
VO = {
arguments: {
0: '王小明',
length: 1
},
age: '22',
personAge: '局部函数执行上下文' //pointer to function f()
}
stateDiagram-v2
变量对象(VO) --> arguments
变量对象(VO) --> ...函数声明
变量对象(VO) --> ...变量属性