web前端学习 JS预编译,执行上下文,变量函数提升

web前端学习 JS预编译,执行上下文,变量函数提升

这几天听学长们讲课,发现很多东西没了解到
自己也一直没写博客的习惯,正好从现在开始慢慢养成这个习惯

JavaScript运行

  1. 语法分析
  2. 预编译
  3. 解释执行

变量提升

函数及变量的声明都将被提升到函数的最顶部。本质还是受到了预编译影响
下面这个例子可能不是很好,但就是这个让我了解到这些问题

	var a = 1;
	function b(){
		a = 10;
		return;
		function a(){
			console.log("1st"+a);
		}
	}
	b();
	console.log("this="+a);//this=1
var a = 1;
//全局执行上下文

function b(){
    a = 10;
    return;
    function a(){
        console.log("1st"+a);
    }
}
b();
//执行b();=>函数上下文(全局执行上下文被压入调用栈底)
//function b(){
//    a = 10;
//   return;
//    function a(){
//        console.log("1st"+a);
//    }
//}
//a首先为undefined,没有var let等字段,在函数内部找到了function a,此时a被赋值为函数,变成函数b中的局部变量 接着a赋值为10,return后函数上下文环境出栈销毁,最后
console.log("this="+a);//this=1,输出a=1

用伪代码看可能会好一点

GO = {             //GO全局对象(Global Object)
    a: undefined,
    b : function b(){
        //...
    }
}

GO = {
    a : 1,
    b: function b(){
        //...
    }
}
//--> 进入函数执行上下文  预编译
AO = {
    a: undefined,
}
//-->
//此时a被赋值为函数,成为 函数b中的局部变量,没有覆盖全局对象中的a
AO = {
    a = function a(){
        //....
    }
}
//--> 执行解释
AO = {
    a : 10,
}
//-->return;   函数执行上下文出栈销毁
GO = {
    a:1
}

执行上下文

执行上下文有且只有三类,全局执行上下文函数上下文,eval上下文(很少用)

全局执行上下文

全局执行上下文只有一个,在客户端中一般由浏览器创建=>window对象

window对象还是var声明的全局变量的载体

函数上下文

每当一个函数被调用时都会创建一个函数上下文

同一个函数被多次调用,都会创建一个新的上下文

**执行上下文栈**用于存储代码执行期间创建的所有上下文

  1. 创建阶段

    This绑定=>创建词法环境组件=>创建变量环境组件

    词法环境用来储存函数声明和变量(letconst)绑定,变量环境用来储存var变量绑定

    函数声明与var声明的变量在创建阶段已经被赋予了一个值,var声明被设置为了undefined,函数被设置为了自身函数,而let ,const被设置为未初始化。

  2. 执行阶段

    变量赋值=>函数引用=>执行其他代码

  3. 销毁阶段
    在这里插入图片描述
    在这里插入图片描述

预编译

预编译确实在script代码内执行前发生了 但是它大部分会发生在函数执行前

var a = 1;
console.log(a);
function test(a) {
  console.log(a);
  var a = 123;
  console.log(a);
  function a() {}
  console.log(a);
  var b = function() {}
  console.log(b);
  function d() {}
}
var c = function (){
console.log("I at C function");
}
console.log(c);
test(2);

预编译(全局执行上下文)

//抽象描述
GO/window = {      //GO全局对象(Global Object)
    a:undefined,
    c:undefined,// var b = function(){}  为赋值语句,函数也是一种数据类型,所以变量c在预编译时为undefined   var b = function b(){}也同理 预编译时为undefined
    test:function(a){
        console.log(a);
        var a = 123;
        console.log(a);
        function a(){}
        console.log(a);
        var b = function(){}
        console.log(b);
        function d(){}
    }
    
}

解释执行代码(到test(2)之前)

//抽象描述
GO/window = {
    a:1,
    c:function(){
        console.log("I at C function");
    },
    test:function(a){
        //.... 
    }
}

执行到test(2),

预编译(函数上下文)

//抽象描述
AO = {
    a:undefined,
    b:undefined,
}

—>

AO = {
    a: 2,//实参形参统一
    b: undefined,
}

—>

AO = {
    a: function a(){}  //a,d函数声明,并赋值函数体
    b:undefined
    d: function d(){}
}

解释执行(test(2))

AO = {
    a:function a(){}
    b:undefined    
    d:function d(){}
}
-->   //var = 123 赋值
AO = {
    a:123,
    b:undefined,
    d:function d(){}
}
-->  //var b = function(){}
AO = {
    a:123,
    b:function(){}
    d:function d(){}
}

执行结果

1
ƒ(){
console.log("I at C function");
}
ƒ a() {}
123
123
ƒ () {}

参考文章:
JS执行上下文
JS预编译

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值