当前位置:网站首页>用一个例子理解JS函数的底层处理机制
用一个例子理解JS函数的底层处理机制
2020-11-06 20:53:00 【mttwind】
个人笔记,如有错误烦请指正
以下面代码的运行举例,一行行进行运行的解析
var x = [12, 23];
function fn(y) {
y[0] = 100;
y = [100];
y[1] = 200;
console.log(y);
}
fn(x);
console.log(x);
var x = [12, 23];运行如下
- 开辟堆内存,创建数组值,假设堆内存的地址为0x000000
- 声明变量
x - 赋值,即将
x指向堆内存的地址0x000000
接着
function fn(y) {
y[0] = 100;
y = [100];
y[1] = 200;
console.log(y);
}
运行如下
上面这段代码是创建一个函数的过程。和创建一个变量类似:
- 都是声明一个变量存储值
- 步骤一样:第一步也是先创建一个堆内存,里面存的是函数,这个堆内存有一个地址,然后把地址赋值给变量
- 声明:方式类似函数名也算变量,当我们声明函数
function fn(y){...}时,相当于我们声明了一个变量,只不过值是函数。类似于var fn = function (y){...}的函数表达式。最终把一个函数作为值赋值给一个变量或者其他
所以创建一个函数,详细的执行顺序如下
- 首先开辟一个堆内存,存储函数的值(假设地址为0x000001)
- 对象的值在堆内存当中,存储的是它的键值对
- 函数的值在堆内存当中,存储的是它的代码,而且是以字符串的形式存储的
- 创建函数的时候,就声明了它的作用域(scope),scope值是当前创建函数的时候所处的上下文,即在哪个上下文中创建的,作用域就是谁

- 接着声明变量
fn,并且指向堆内存地址(假设为0x000001)
函数执行的步骤
fn(x);运行如下(函数执行的步骤)
- 函数执行时,永远传的是值,
fn(x)传的是x的值,即x指向的0x000000堆内存地址 fn(0x000000)形成一个全新的私有上下文EC(fn)- 在函数形成的新的上下文中,生成一个私有化变量对象AO,用来存储当前上下文中声明的变量(Active Object活动对象,简称AO,变量对象的一种,类似全局上下文中的全局变量)

- 内部代码执行之前发生的事
- 初始化作用域链scope-chain <EC(fn1),EC(G)>,链的两头是 <当前自己的私有上下文,函数的作用域(创建函数的时候所在的上下文)>,链的右侧也叫当前上下文的'上级上下文'
- 初始化this
- 初始化argument
- 在当前上下文中,声明一个形参变量,并且把传递的实参值赋值给它
- 变量提升

- 进栈执行代码
- 出栈释放
函数进栈执行代码的详细步骤
接着说说上面第5步的详细步骤
把之前创建的函数,在堆内存中存储的代码字符串拿出来转换为代码一行一行的执行执行。
私有上下文中代码执行中如果遇到一个变量,首先看是否为自己的'私有变量',如果是'私有'的,则操作自己的,和外界没有必然的关系,如果不是自己私有的,则基于作用域链,向其上级上下文中查找,看是否为上级上下文中私有的,如果也不是,继续向上查找......一直找到EC(G)全局上下文为止,我们把这种查找过程称之为 作用域链查找机制 所以
y[0] = 100
y = [100]
y[1] = 200
是这样的执行的:
-
y[0] = 100,y现在存储的内存地址为0x000000,所以修改这个地址下的值:
-
y = [100],出现了新的对象值,所以要开辟新的堆内存0x000002,创建值,赋值
-
y[1] = 200,将0x000002地址对应的对象的值进行修改
-
console.log(y);这个y就是0x000002对应的值[100,200]操作的是私有变量y
fn函数至此执行完毕。
接着执行外面的console.log(x);,此时的x为全局变量对象中的x,对应的地址为0x000000,所以直接进行输出[100,23]

如果fn执行完之后,继续执行其他函数,同样会经历这样的流程。形成新的上下文,进栈执行...如果函数非常多,会一直进栈,占内存会越来越大。所以为了优化,浏览器会默认做出很多回收机制
结果与总体流程
结果

总体流程图

其他说明点
js上下文分类
js上下文(哪一个区域下执行)分类
- 全局上下文EC(G)
- 函数执行形成的私有上下文
- 块级私有上下文
什么是私有变量
私有变量是私有上下文声明的变量,包含
- 形参
- 代码执行的时候声明的变量
var/let/const/function... 注意与全局变量区别,没有直接关系,但是可能会存在一些间接关系,比如下面这段代码下全局变量x的值是0x000000,通过函数,将0x000000传给了私有变量y,y也是0x000000
function fn(y) {
y[0] = 100;
y = [100];
y[1] = 200;
console.log(y);
}
fn(x)

版权声明
本文为[mttwind]所创,转载请带上原文链接,感谢
https://my.oschina.net/u/4595551/blog/4668644
边栏推荐
- CCR炒币机器人:“比特币”数字货币的大佬,你不得不了解的知识
- It's so embarrassing, fans broke ten thousand, used for a year!
- 关于Kubernetes 与 OAM 构建统一、标准化的应用管理平台知识!(附网盘链接)
- 一篇文章带你了解CSS对齐方式
- Python Jieba segmentation (stuttering segmentation), extracting words, loading words, modifying word frequency, defining thesaurus
- Character string and memory operation function in C language
- 做外包真的很难,身为外包的我也无奈叹息。
- vue任意关系组件通信与跨组件监听状态 vue-communication
- Don't go! Here is a note: picture and text to explain AQS, let's have a look at the source code of AQS (long text)
- 数据产品不就是报表吗?大错特错!这分类里有大学问
猜你喜欢

keras model.compile Loss function and optimizer

JVM memory area and garbage collection

Grouping operation aligned with specified datum

Tool class under JUC package, its name is locksupport! Did you make it?

CCR炒币机器人:“比特币”数字货币的大佬,你不得不了解的知识

vue任意关系组件通信与跨组件监听状态 vue-communication

How to select the evaluation index of classification model

一篇文章带你了解CSS 分页实例

“颜值经济”的野望:华熙生物净利率六连降,收购案遭上交所问询

小程序入门到精通(二):了解小程序开发4个重要文件
随机推荐
Vue 3 responsive Foundation
前端工程师需要懂的前端面试题(c s s方面)总结(二)
Using consult to realize service discovery: instance ID customization
I think it is necessary to write a general idempotent component
前端基础牢记的一些操作-Github仓库管理
加速「全民直播」洪流,如何攻克延时、卡顿、高并发难题?
ES6 essence:
PHPSHE 短信插件说明
Python Jieba segmentation (stuttering segmentation), extracting words, loading words, modifying word frequency, defining thesaurus
Filecoin的经济模型与未来价值是如何支撑FIL币价格破千的
Our best practices for writing react components
Python download module to accelerate the implementation of recording
2019年的一个小目标,成为csdn的博客专家,纪念一下
What is the difference between data scientists and machine learning engineers? - kdnuggets
Character string and memory operation function in C language
使用 Iceberg on Kubernetes 打造新一代云原生数据湖
Filecoin最新动态 完成重大升级 已实现四大项目进展!
采购供应商系统是什么?采购供应商管理平台解决方案
前端都应懂的入门基础-github基础
Programmer introspection checklist