js 执行上下文

前言

什么执行上下文?

就是当前代码将会在什么样的环境运行。

执行上下文分为3类:

1.全局执行上下文,在全局中的上下文

2.函数执行上下文,在函数中的上下文

3.Eval函数执行上下文,很少使用。如果安全最好使用Function。

全局执行上下文:

这是默认的、最基础的执行上下文。不在任何函数中的代码都位于全局执行上下文中。

它做了两件事:

1. 创建一个全局对象,在浏览器中这个全局对象就是 window 对象。

2. 将 this 指针指向这个全局对象。一个程序中只能存在一个全局执行上下文。

在此就不过多介绍全局执行上下文,主要介绍函数执行上下文。

函数执行上下文

每一个函数执行的时候都会有一个执行前,都会有一个函数执行上下文,那么是如何管理的呢?

有一個執行上下文棧:

其实上面这个图不准确。

看到图的main,也就是栈的最底层。显示的应该是globalContext.

执行console.log的时候log的上下文进栈,当要执行bar的时候,bar的上下文进栈,然后far上下文进栈,当far执行完毕,far的上下文出栈。

这样做的好处就是,当执行代码的时候,只要取栈顶,那么得到的就是当前上下文执行的栈。

执行上下文的生命周期:

创建阶段 → 执行阶段 → 回收阶段

创建阶段

当函数被调用,但未执行任何其内部代码之前,会做以下三件事:

1.创建变量对象:首先初始化函数的参数 arguments,提升函数声明和变量声明。下文会详细说明。

2.创建作用域链(Scope Chain):在执行期上下文的创建阶段,作用域链是在变量对象之后创建的。

作用域链本身包含变量对象。作用域链用于解析变量。

3.当被要求解析变量时,JavaScript 始终从代码嵌套的最内层开始,如果最内层没有找到变量,就会跳转到上一层父作用域中查找,直到找到该变量。

确定 this 指向

先来看下变量对象:

  1. 变量声明提升
console.log(a); // undefined
var a = 10;

简单点就是说,在程序运行之前扫码一遍,把变量进树。然后赋值undefine.

2.函数声明提升

在程序运行之前扫码一遍,把函数进树,注意是将函数对象进树,此时是会实例化的。

注意事项:

当函数申明提示和变量声明提升 冲突的时候,那么函数申明为主

3.确定this

直接给图看哈。

作用域链:

什么是作用域链?是这样子的。

我们发现有一个问题,那就是我们可以访问全局变量,这神奇吗?

可能有些人觉得,这有什么?我们的思维已经固定了,认为不就是访问全局变量吗。

它的实现是这样子的:

上下文时候有一个[[scope]],存储的是上级上下文的变量对象。

var scope = "global scope";
function checkscope(){
    var scope2 = 'local scope';
    return scope2;
}
checkscope();

checkscope.[[scope]] = [
globalContext.VO
];

那么这时候可以回顾一下上下文是如何创建的。

先创建上下文对象,假如checkscope的上下文,我命名为checkscopeContext

1.checkscope 函数被创建,保存作用域链到 内部属性[[scope]]

checkscope.[[scope]] = [
globalContext.VO
];

2.执行 checkscope 函数,创建 checkscope 函数执行上下文,checkscope 函数执行上下文被压入执行上下文栈

ECStack = [
checkscopeContext,
globalContext
];

3.checkscope 函数并不立刻执行,开始做准备工作,第一步:复制函数[[scope]]属性创建作用域链

checkscopeContext = {
Scope: checkscope.[[scope]],
}

4.第二步:用 arguments 创建活动对象,随后初始化活动对象,加入形参、函数声明、变量声明

checkscopeContext = {
AO: {
arguments: {
length: 0
},
scope2: undefined
},
Scope: checkscope.[[scope]],
}

5.第三步:将活动对象压入 checkscope 作用域链顶端

checkscopeContext = {
AO: {
arguments: {
length: 0
},
scope2: undefined
},
Scope: [AO, [[Scope]]]
}
后面进入执行步骤,当函数执行完毕弹出。

原文地址:https://www.cnblogs.com/aoximin/p/12460228.html