JavaScript—执行上下文和执行上下文栈

    科技2022-08-01  120

    文章目录

    1.变量提升与函数提升2.执行上下文3.执行上下文栈

    1.变量提升与函数提升

    1.变量声明提升: *通过var定义(声明)的变量,在定义语句之前就可以访问到 *访问的值为:undefined; 2.函数声明提升: *通过function声明的函数,在函数代码之前就可以直接调用 *访问的值为:函数定义 <script type="text/javascript"> var a=3; function fn (){ console.log(a); var a=4 } fn(); //返回undefined //原因:首先函数中有变量a,则不考虑全局的a=3; //然后在函数中先定义a为undefined,再输入,最后再给a赋值为4 console.log(b); //返回undefined,可执行,变量提升; fn2(); //可执行,函数提升; fn3(); //不可执行,因为用的是关键字var,则为变量提升; var b=3; function fn2 (){ console.log('fn2()'); } var fn3=function (){ console.log('fn3'); } </script>

    问题:变量提升和函数声明提升是如何产生的??

    2.执行上下文

    1.代码分类: *全局代码 *函数(局部)代码 2.全局执行上下文: 在执行全局代码前,将window确定为全局执行上下文对象 对全局数据进行预处理: 1.var定义的全局变量——>undefined, 添加为window的属性; 2.function声明的全局函数——>定义,赋值(fun), 添加为window的方法; 3.this——>赋值(window) 开始执行全局代码; 3.函数执行上下文: *在调用函数,准备执行函数体之前,创建对应的函数执行上下文对象 (函数执行上下文对象是一个虚拟的对象,作用类似全局中的window) *对函数中的数据进行预处理: 1.形参变量——>赋值(实参) , 添加为执行上下文对象的属性; 2.arguments——>赋值(所有实参) , 添加为上下文对象的属性; 3.var定义的局部变量——>undefined , 添加为执行上下文对象的属性; 4.function声明的函数——>赋值(fun) , 添加为执行上下文对象的方法; 5.this ——>赋值(调用函数的对象) *开始执行函数体代码;

    a.变量提升与函数提升产生的原因:变量提升与函数提升就是执行上下文预处理的效果。 b.进行执行上下文预处理后,就按顺序进行执行;如果在执行有有函数,则再次进行函数的预处理。 c.执行上下文环境(对象)是动态的,调用函数时创建,函数调用结束时上下文环境(对象)就会被自动释放;(局部变量自动释放)

    <script type="text/javascript"> //全局执行上下文 console.log(e); //undefined console.log(window.e); //预处理会将e添加为window的属性,所以e和window.e是一样的。 //this表示的是window; var e=12; function fun(){ console.log("fun()"); } //函数执行上下文 function fn(a1){ console.log(a1); //2 console.log(a2); //undefined a3(); //a3() console.log(this); //window console.log(arguments); //2,3 伪数组 var a2=3; function a3(){ console.log('a3()'); } } fn(2,3); //函数执行上下文对象,在调用函数时产生; </script>

    3.执行上下文栈

    执行上下文栈: 1.在代码执行前,js引擎就会创建一个栈来存储管理所有的执行上下文对象; 2.在全局执行上下文window对象确定后,将其添加到栈中(压栈); 3.在函数执行上下文对象创建后,将其添加到栈中(压栈); 4.在当前函数执行完后,将栈顶的对象移除(出栈); 5.当所有的代码执行完后,栈中只剩下window; <script type="text/javascript"> var a=10; //1.产生全局执行上下文window; var bar =function (x){ var b=5; foo(x+b); //3.产生foo函数的执行上下文对象; } var foo=function (y){ var c=5; console.log(a+c+y); } bar(10); //2.产生bar函数的执行上下文对象; </script>

    栈结构:后产生的执行上下文对象,一定是先执行。

    <script type="text/javascript"> console.log("gb:"+i); var i=1; foo(1); //产生执行上下文, function foo(i){ if(i==4){ return } console.log("fb:"+i); //执行三次i=1,i=2,i=3 foo(i+1); //递归调用,在函数内部调用自己; console.log("fe:"+i); //递归调用三次,执行三次i=3,i=2,i=1 } console.log("ge:"+i); </script> 1.依次输出什么? gb:undefined fb:1 fb:2 fb:3 fe:3 fe:2 fe: 1 ge: 1 2.整个过程中产生了几个执行上下文? 产生5次;1+1+3 var c=1; function c(c){ console.log(c); } c(2); //结果为报错; //原因:先变量c提升了,然后后执行c=1 //执行c=1后,此时c就是一个变量了,调用c(2)则会报错; //函数还没调用,则函数里面的代码并未执行;
    Processed: 0.011, SQL: 9