一、执行上下文
执行上下文EC(execution context)
执行上下文功能:代码执行之前的准备工作,确定当前环境下变量的取值。
执行上下文目的:用来存放数据的。
分类:
1、全局上下文 (全局上下文只有一个 (打开一个窗口就会创建一个全局上下文,关闭页面就销毁))
2、局部上下文 (函数执行完毕销毁 (调用函数就会创建一个局部上下文))
3、eval上下文 (了解) :解读字符串中代码。
执行栈( 存放执行上下文 最底层下GO 最上面层是正在调用执行的函数 注:FILO 进栈(压栈),出栈 规则先进后出)
window 全局对象
变量提升:var声明的变量(除函数内) 值提升变量的声明
函数提升:字面量声明函数(函数声明) 提升整个函数体
执行上下文的声明周期:
1、创建(变量和函数提升)
2、执行(函数体的代码,会改变当前变量和全局变量的值)
3、销毁(指销毁执行上下文的作用域链)
全局执行上下文
1、全局对象window (GO)
局部执行上下文:
1、创建局部对象 AO (调用才有AO) 执行对象
2、预编译
a>形参 变量
b>形参 变量赋值
c>形参和实参相统一
d>函数提升
e>确定this的指向(由调用者确定)
f>确定作用域 (词法环境 在哪里声明,就确定在哪里)
g>初始化作用域链
active Object
3、执行函数体代码
4、作用域链 当前没有 就找离它当前包含最近的声明值 包含中就没有去找全局的
{
i=0
}
console .log(i) //0 i前自动补全可以出去 i前加var 出不去
var i=1;
function f70(){
console.log(i);
let i=2;//暂时性死区 告知当前AO拥有该变量 Cannot access ‘i’ before initialization(应该在之前初始化)
}
f70();
作用域:静态的
执行上下文:动态的(在调用前一刻创建上下文) 只有函数才会产生上下文
执行栈(先存放G0在看其它)
for里面有var 为什么提升全局变量 因为全局(GO)
二、闭包
什么是闭包?(需要满足以下两个条件才是闭包)
1、内部嵌套函数、嵌套函数引用外部变量。
2、内部函数被外部引用。
为什么使用闭包?
1、解决无法使用的内部变量
2、解决全局变量污染问题
自由变量:函数内部使用外部变量,这个变量就是自由变量。
// 注:跨域的变量都是自由变量,即变量声明和使用不在同一个作用域。
let j = 1;
function f70() {
let i = 0;
function f71() {
//这里的i和j是自由变量
let k;
console.log(i + j + k);
}
}
递归
定义:自己调用自己
注:一定要有结束(出口);
// 递归
const arr = [1, 2, "a", "f70", [true, false],["xxx","yyy",["zzz","0"]]];
let dataarr=[];
function f70(temp)
{
for(let i=0;i<temp.length;i++)
{
// 判断是不是数组
if(typeof temp[i]=="object")
{
f70(temp[i]);
}
else{
dataarr.push(temp[i]);
}
}
temp.map(item=>typeof item =='object'? f70(item):dataarr.push(item));
// temp.forEach(item=>typeof item =='object'? f70(item):dataarr.push(item));
}
f70(arr);
console.log(dataarr);