JavaScript执行上下文复习笔记

124 阅读5分钟

执行上下文

1. 作用域

1.1 作用域的概念

作用域是指程序源代码中定义变量的区域。

作用域规定了如何查找变量,也就是确定当前执行代码对变量的访问权限。

JavaScript 采用词法作用域(lexical scoping),也就是静态作用域

1.2 静态作用域与动态作用域

静态作用域,即词法作用域,函数的作用域在函数定义的时候就决定了,JavaScript是静态作用域

动态作用域,函数的作用域是在函数调用的时候才决定的,bash是动态作用域

2. 执行上下文

2.1 可执行代码

JavaScript 的可执行代码(executable code)的类型:

全局代码、函数代码、eval代码

与之对应也就有了执行上下文的分类:

全局执行上下文、函数执行上下文、Eval函数执行上下文

2.2 执行上下文分类

当执行一个函数的时候,就会进行准备工作,而这个准备工作更专业的说法就是执行上下文

全局执行上下文

任何不在函数内部的代码都在全局上下文中,全局执行上下文在浏览器情况下,会创建一个全局的widow对象,并且设置this的值等于window,一个程序中只会有一个全局执行上下文

当JavaScript开始解释执行代码的时候,最先遇到的是全局代码,因此,初始化的时候会向执行上下文栈ECStack压入一个全局执行上下文 globalContex,只有当整个应用程序结束的时候,ECStack 才会被清空,所以程序结束之前, ECStack 最底部永远有个 globalContext

函数执行上下文

当执行一个函数的时候,就会创建一个执行上下文funcContex,并且压入执行上下文栈ECStack,当函数执行完毕的时候,就会将函数的执行上下文funcContex从栈中弹出

如果函数中调用了另外一个函数,则在外层函数执行上下文创建之后,会创建内层函数执行上下文,内层函数调用结束之后,内层函数执行上下文从栈中弹出,外层函数执行成功之后,外层函数执行上下文从栈中弹出

Eval函数执行上下文

执行在 eval 函数内部的代码也会有它属于自己的执行上下文

2.3 执行上下文的属性

变量对象

变量对象是与执行上下文相关的数据作用域,存储了在上下文中定义的变量和函数声明

全局上下文的变量对象

全局上下文中的对象就是全局对象,可以访问所有其他所有预定义的对象、函数和属性

函数执行上下文的变量对象

当创建函数上下文后,还未执行代码:

变量对象会包括:

  1. 函数的所有形参 (如果是函数上下文)
    • 由名称和对应值组成的一个变量对象的属性被创建
    • 没有实参,属性值设为 undefined
  2. 函数声明()
    • 由名称和对应值(函数对象(function-object))组成一个变量对象的属性被创建
    • 如果变量对象已经存在相同名称的属性,则完全替换这个属性
  3. 变量声明
    • 由名称和对应值(undefined)组成一个变量对象的属性被创建;
    • 如果变量名称跟已经声明的形式参数或函数相同,则变量声明不会干扰已经存在的这类属性

代码执行:

顺序执行代码,会完成变量赋值(修改变量的值),函数引用,以及执行其他代码

总结
  1. 全局上下文的变量对象初始化是全局对象
  2. 函数上下文的变量对象初始化只包括 Arguments 对象
  3. 在进入执行上下文时会给变量对象添加形参、函数声明、变量声明等初始的属性值
  4. 在代码执行阶段,会再次修改变量对象的属性值

举例:

console.log(foo); // function foo

function foo(foo) {
    console.log("foo");
}

var foo = 1;
console.log(foo); // 1

// -----------------------------
var foo;
console.log(foo); /// function foo
function foo(foo) {
    console.log("foo");
};

作用域链

当查找变量的时候,会先从当前上下文的变量对象中查找,如果没有找到,就会从父级(词法层面上的父级)执行上下文的变量对象中查找,一直找到全局上下文的变量对象,也就是全局对象。这样由多个执行上下文的变量对象构成的链表就叫做作用域链

函数的作用域在函数定义的时候就决定了原因:

函数有一个内部属性 [[scope]],当函数创建的时候,就会保存所有父变量对象到其中,

this

全局执行上下文中,this指向全局对象

函数执行上下文中,this取决于函数是如何被调用的,如果是被一个对象调用,则this指向该对象,否则this是全局对象(严格模式下this是undefined)

3. 参考资源