美文网首页
JS 作用域和执行上下文[3] — 执行上下文

JS 作用域和执行上下文[3] — 执行上下文

作者: 弱冠而不立 | 来源:发表于2020-10-05 15:28 被阅读0次

参考文章:
[译] 理解 JavaScript 中的执行上下文和执行栈
彻底明白作用域、执行上下文
JavaScript 执行上下文和执行栈
深入理解 JavaScript 作用域和作用域链
谈谈 JavaScript 的作用域
Javascript 的 this 用法

1. 什么是执行上下文?

简而言之,执行上下文就是当前 JavaScript 代码被解析和执行时所在环境的抽象概念, JavaScript 中运行任何的代码都是在执行上下文中运行。

2. 执行上下文类型分类

  • 全局执行上下文

这是默认的、最基础的执行上下文。
不在任何函数中的代码都位于全局执行上下文中。
它做了两件事:
1.创建一个全局对象,在浏览器中这个全局对象就是 window 对象。
2.将 this 指针指向这个全局对象。一个程序中只能存在一个全局执行上下文。

  • 函数执行上下文

每个函数都拥有自己的执行上下文,但是只有在函数被调用的时候才会被创建。
(注:只有调用函数时才会创建该函数的执行上下文,而不是声明函数时)
一个程序中可以存在任意数量的函数执行上下文,因为一个程序中的函数数量和被调用次数是未知的。

  • eval 函数执行上下文

运行在 eval 函数中的代码也获得自己的执行上下文,但是由于这个函数存在很大安全和性能问题,已经被强烈不推荐使用,这里就一笔带过。

简单概括一下:不在函数里的就是全局上下文,其他都是函数执行上下文

上下文执行栈

栈,具有后进先出结构(LIFO, Last In First Out),具有 push 和 pop 功能。代码执行期间所创建的执行上下文就是它存储的。

那创建的执行上下文什么时候入栈,又什么时候出栈呢?

  • 全局执行上下文:当 JS 引擎首次遇到该脚本程序时,就创建一个全局执行上下文,然后压入执行栈中。所以全局执行上下文是最早进入执行栈的。
  • 函数执行上下文:当函数调用时,创建该函数的执行上下文,然后压入执行栈,在调用结束后出执行栈。

执行上下文创建过程

在这个阶段,执行上下文会分别 创建变量对象、建立作用域链以及确定 this 的指向

执行上下文的变量对象

执行上下文中定义了变量或函数有权访问的其他数据,决定了它们各自的行为。

每个执行上下文中都有一个与之关联的变量对象(variable object)
上下文定义的所有变量和函数都保存在这个对象中。

  • 全局执行上下文的变量对象:也可称作为全局对象,我们可以用 this 来访问。(浏览器环境 this 指向 window,node 环境 this 指向 global)
  • 函数执行上下文变量对象:函数执行上下文变量对象可以叫活动对象(activation object,这里简称 AO),这么称呼的原因是当进入函数执行上下文中,这个执行上下文才被激活,此刻属性才能被访问。(变量对象和活动对象是同一种东西,但是变量对象进入执行阶段之前是不能被访问的,进入执行阶段之后,变量对象转变为活动对象,里面的属性才可以被访问。类似Vue的生命周期。)

根据这个原理,我们也能很好理解var声明的变量的变量提升的概念,在代码执行前,先经过上下文的创建阶段,代码中的变量和函数都保存在执行上下文的变量当中,然后在执行过程中就可以根据执行顺序和变量需要进行调整。

this 指向

  • 作为函数调用 =========> this 指向全局变量
  • 对象方法调用 =========> this 指向对象
  • 构造函数调用 =========> this 指向构造函数构造的新对象
  • call/apply,bind调用 ====> this 指向绑定的对象

相关文章

网友评论

      本文标题:JS 作用域和执行上下文[3] — 执行上下文

      本文链接:https://www.haomeiwen.com/subject/rampyktx.html