JavaScript-函数的底层执行机制

函数的底层执行机制

函数的创建

一个函数的创建会在 Heap 堆内存中开辟一块空间来存储函数。对象在创建会在堆内存中存储对象的键值对,而函数在堆内存中会存储三部分东西:

作用域:[[scope]]
函数字符串
键值对
例如:

let a = [1,2];
function fn(b) {
 b[0] = 3;
  b = [4];
  b[1] = 5;
  console.log(b);
}
fn(a);
console.log(a);

请添加图片描述对象虽然包含函数,但是函数的创建和其他对象的创建在存储内容上存在一些差别:

  1. 在 Heap 堆内存中分配一块空间(16进制地址)。
  2. 存储相关的内容:

函数对象存储三部分

  1. 创建函数的时候声明作用域[[scope]],函数在那个上下文中创建,其作用域就是谁。
  2. 把函数体中的代码当做字符串存储起来。
  3. 把函数当做普通对象存储一些键值对

其余对象存储键值对

  1. 把创建的内存地址赋值给对应的变量或者函数,易变后续的操作。

函数的执行

1. 创建私有上下文
函数一旦执行,就会创建一个全新的私有上下文「进栈」,函数每一次执行 都是重新形成一个全新的私有上下文,和之前执行产生的上下文没有必然的联系,函数中的代码都是在私有上下文中进行执行的。函数进栈执行会创建一个私有变量对象 AO(Active Object),这里区分开 VO。AO 是 VO 的一个分支。在私用上下文中创建的变量都会存储在 AO 中,例如形参、变量提升和函数中定义的变量。

2. 完成初始化操作
完函数进栈后,正式开始执行之前,会进行一些初始化的操作:

  • 初始化作用域链<<自己的私有上下文,作用域>>。

  • 初始化 this (箭头函数没有这一步)。

  • 初始化 arguments (箭头函数没有这一步)。

  • 形参赋值。

  • 变量提升。

3. 代码执行
将堆内存中存在的代码字符串从上往下的顺序进行执行。

4.出栈释放或者保留
正常情况下,代码执行完成之后,私有上下文出栈被回收。但是遇到特殊情况,如果当前私有上下文执行完成之后中的某个东西被执行上下文以外的东西占用,则当前私有上下文就不会出栈释放,也就是形成了不被销毁的上下文,闭包。除了这上面两种情况还有一种情况是,上下文没有被占用,但是要紧接着被用一次,这样没有用完之前是不能释放的,用完在释放,这样就形成了一个临时不被释放 )。

函数每一次执行都是重新形成一个全新的私有上下文,意思就是如果一个函数被执行100次,也会对上面的步骤走100次,并且形成100个执行上下文。正常情况下,函数执行完就会出栈被释放,但是如果不能被释放(闭包),就会一直被保存在内存中,当达到栈内存的极限时就会出现爆栈。

还是用这段代码为例:

let a = [1,2];
function fn(b) {
 b[0] = 3;
  b = [4];
  b[1] = 5;
  console.log(b);
}
fn(a);
console.log(a);

请添加图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

一缕阳光@

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值