js原理之执行上下文

给你一段这样的代码。

function fun() {
	console.log(a);
	var a= 1;
	function a(){
		return 2;
	}
}
fun();

经过代码运行可得:在这里插入图片描述
为何会出现这种结果,这就与执行上下文有关。

执行上下文

基本概念

当调用一个函数时,一个执行上下文就会被创建(激活),执行上下文可以理解成一个运行环境,它会形成一个作用域。运行环境一般可以分为全局环境、函数环境、eval(基本可忽略),而js引擎会以栈的形式管理这些上下文,全局上下文始终处于栈的最底部,而栈顶则是当前正在执行的上下文。

执行上下文的两个周期

文章开始的代码结果与上下文的周期有关。
上下文可以分为创建阶段和代码执行阶段。

创建阶段

在这个阶段,执行上下文会创建变量对象,建立作用域链,以及确定this的指向。
本文主要讲解变量对象(VO variable object)。变量对象主要会经历以下几个过程。

1.建立argument,检测该对象下的参数,建立属性和属性值。
2.检查当前上下文中的函数声明,也就是function关键字声明的函数。以函数名建立属性,属性值指向该函数指向内存地址的引用。若函数名的属性已经存在,则属性将被新的引用所覆盖。
3.检查当前上下文中的变量对象,每找到一个变量声明,就以对象名建立属性,属性值为undefined。若变量名的属性已经存在,为防止函数被修改为undefined,直接跳过,原属性值不改变。

所以文章开头代码在这一阶段后,会建立如下变量对象。

VO = {
	arguments: {...},
	a: <a reference> //表示地址的应用
}

注意: 在找到a变量声明时,变量对象中已有a属性,所以直接到过,并不会建立a: undefined。

代码执行阶段

在这个阶段,主要会做变量赋值,函数应用,以及其他代码执行。

所以文章开头代码的实际执行顺序如下。

function fun() {
	function a(){
		return 2;
	}
	//var a=undefined 由于已存在a属性,所以将直接跳过,不会进行undefined赋值。
	console.log(a);
	a= 1;
}

其他

对于变量提升,我们也可以通过执行上下文的生命周期来描述,在创建阶段,检测上下文中的变量声明,若属性中没有该变量名,则会在变量对象中添加 变量名:undefined ,从而就实现了变量提升。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
JS 脚本的执行原理可以概括为以下几个步骤: 1. 解析:浏览器首先会对 JS 脚本进行解析,将其转换为可执行的代码。解析过程包括词法分析和语法分析,将代码分解为词法单元并构建语法树。 2. 创建全局上下文:在执行之前,浏览器会创建一个全局执行上下文(Global Execution Context),用来存储全局变量、函数声明等信息。 3. 执行代码:按照从上到下的顺序执行代码。遇到函数调用时,会创建一个新的函数执行上下文,并将其加入调用栈(Call Stack)中。 4. 变量与函数声明提升:在代码执行前,会进行变量与函数声明的提升。变量声明会被提升到作用域的顶部,但是初始化的赋值操作不会提升。函数声明会被整体提升到作用域的顶部,可以在声明之前进行调用。 5. 作用域与作用域链:JavaScript采用词法作用域,函数和变量的访问权限由它们在代码中的位置决定。每个函数都会创建一个新的作用域,作用域之间通过作用域链进行连接。 6. 变量赋值与运算:在执行过程中,会进行变量的赋值操作和各种运算操作。JavaScript中的运算符包括数学运算符、逻辑运算符、赋值运算符等。 7. 垃圾回收:当 JS 引擎确定某个对象不再被引用时,会自动触发垃圾回收机制,将其占用的内存释放回来。 通过以上步骤,JS 脚本的代码会被逐行执行,从而实现相应的功能。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值