执行上下文 也就是预编译
函数执行上下文:一个函数运行之前,创建的一块内存空间,空间中包含有该函数执行所需要的数据,为该函数执行提供支持。
执行上下文栈:call stack,所有执行上下文组成的内存空间。
栈:一种数据结构,先进后出,后进先出。
全局执行上下文:所有JS代码执行之前,都必须有该环境。其中第一个执行环境是全局执行环境
this指向
全局this指向window
直接调用函数,this指向全局对象
在函数外,this指向全局对象
通过对象调用或new一个函数,this指向调用的对象或新对象
VO 变量对象
Variable Object:VO 中记录了该环境中所有声明的参数、变量和函数
Global Object: GO,全局执行上下文中的VO
Active Object:AO,当前正在执行的上下文中的VO
首先会创建一个全局的环境也就是GO
1:查找通过var声明的变量,并将它设置为unfinished,如果已有该名称,则直接忽略
2:查找通过自变量声明的函数.并将他们的值设置为指向函数对象 ,如果已存在该名称则会覆盖,
其次是 VO 与 AO
1:确定所有形参值以及特殊变量arguments
2:查找通过var声明的变量,并将它设置为unfinished,如果已有该名称,则直接忽略
3:查找通过自变量声明的函数.并将他们的值设置为指向函数对象 ,如果已存在该名称则会覆盖,
当一个上下文中的代码执行的时候,如果上下文中不存在某个属性,则会从之前的上下文寻找。
作用域链
- VO中包含一个额外的属性,该属性指向创建该VO的函数本身
- 每个函数在创建时,会有一个隐藏属性
[[scope]]
,它指向创建该函数时的AO - 当访问一个变量时,会先查找自身VO中是否存在,如果不存在,则依次查找
[[scope]]
属性
某些浏览器会优化作用域链,函数的[[scope]]
中仅保留需要用到的数据。
var g = 0;
function A() {
var a = 1;
function B() {
var b = 2;
var C = function() {
var c = 3;
console.log(c, b, a, g);
}
C();
}
B();
}
A();
上面代码的作用域链以及执行上下文 如下