从底层理解this是什么
作者:dellyoung
出处:
何为this关于this , 我提出了下面几个问题:
- this存放在哪里?
- this是如何出现 , 又是如何消失的?
- this有什么作用?
执行上下文为清晰讲述 this 结合了 《浏览器工作原理与实践》 部分内容
咱们先看下这段代码的函数调用过程:
var a = 2function add(){var b = 10returna+b}add()
这段代码很简单 , 先是创建了一个 add 函数 , 接着在代码的最下面又调用了该函数 。在执行到函数 add() 之前 , 也就是第6行之前 , JavaScript 引擎会为上面这段代码创建全局执行上下文 , 包含了声明的函数和变量 , 你可以参考下图:
文章插图
从图中可以看出 , 代码中全局变量和函数都保存在全局上下文的变量环境中 。
执行上下文准备好之后 , 便开始执行全局代码 , 当执行到 add 这儿时 , JavaScript 判断这是一个函数调用 , 那么将执行以下操作:
- 首先 , 从全局执行上下文中 , 取出 add 函数代码 。
- 其次 , 对 add 函数的这段代码进行编译 , 并创建该函数的执行上下文和可执行代码 。
- 最后 , 执行代码 , 输出结果 。
也就是说在执行 JavaScript 时 , 可能会存在多个执行上下文 , 那么 JavaScript 引擎是如何管理这些执行上下文的呢?
答案是 通过JavaScript调用栈来管理的, 接下来咱们来看下什么是JavaScript调用栈 。
JavaScript调用栈咱们知道 , JavaScript执行过程中 , 内存空间主要分为栈空间和堆空间(代码空间先不用管) 。
什么是 JavaScript 的调用栈:代码执行过程中 , JavaScript 引擎会将执行上下文压入栈空间中 , 通常把这种用来管理执行上下文的栈称为执行上下文栈 , 又称调用栈 。
接下来我们一步步地分析在下面代码的执行过程中 ,JavaScript 调用栈的状态变化情况:
var a = 2function add(b,c){return b+c}function addAll(b,c){var d = 10result = add(b,c)returna+result+d}addAll(3,6)
第一步 , 创建全局上下文 , 并将其压入栈底 。如下图所示:
文章插图
从图中你也可以看出 , 变量 a、函数 add 和 addAll都保存到了全局执行上下文的变量环境对象中 。
全局执行上下文压入到调用栈后 , JavaScript 引擎便开始执行全局代码了 。 首先会执行 a=2 的赋值操作 , 执行该语句会将全局上下文变量环境中 a 的值设置为 2 。
设置后的全局上下文的状态如下图所示:
文章插图
第二步是调用 addAll 函数 。 当调用该函数时 , JavaScript 引擎会编译该函数 , 并为这个函数创建一个执行上下文 , 最后将该函数的执行上下文压入栈中 , 如下图所示:
文章插图
第三步 , 当执行到 add 函数调用语句时 , 同样会为其创建执行上下文 , 并将其压入调用栈 , 如下图所示:
文章插图
当 add 函数返回时 , 该函数的执行上下文就会从栈顶弹出 , 并将 result 的值设置为 add 函数的返回值 , 也就是 9 。 如下图所示:
推荐阅读
- 资本的价值观:996是福报?底层人物就是用命换钱?
- 数据|新基建时代,高大全的数据管理解决方案是怎样“炼”成的?
- 魅族 17 系列即将升级 Android 11 系统底层
- 官方爆料:魅族Flyme的Android 11底层安排上了?
- 菜鸟学编程,不懂C++ this指针?还不赶快来学一学
- 田间地头万亿级争锋:互联网巨头与垂直玩家共舞 供应链能力考验底层逻辑
- 深入理解Netty编解码、粘包拆包、心跳机制
- 魅族17升级Android 11系统底层倒计时 12·23内测招募
- 社区团购巨头纷纷入场,底层商贩、老百姓或将成为“鱼肉”
- HFL Redis_10_set类型底层存储数据结构