JavaScript上下文

2017-10-25  本文已影响0人  Evangelist

JavaScript中有三种运行环境

全局环境:JavaScript最开始运行的默认环境

函数环境:函数执行时,函数内的环境

Eval环境:eval()运行环境,不建议使用

JavaScript引擎遇到可执行的程序(以函数为例),会为这段程序创建一个执行上下文Execution context,EC),执行上下文暂时理解为当前程序的执行环境。每遇到不同的程序(函数),就会为该程序创建一个执行上下文。这些执行上下文就构成一个执行上下文栈(Execution context stack,ECS)。

例1:

var a = "globalVar";

function outerFunc(){

var b = "outerVar";

function innerFunc(){

var c = "innerVar";

}

innerFunc();

}

outerFunc()

程序执行先进入GlobalEC,GlobalEC入栈;然后进入outerFuncEC,outerFuncEC入栈;最后进入innerFuncEC,innerFuncEC入栈。然后程序执行,innerFunc执行完,innerFuncEC出栈;outerFunc执行完,outerFuncEC出栈;程序执行完,GlobalEC出栈。

每一段程序的执行可以分为两个阶段,执行上下文阶段和程序执行阶段。

执行上下文:又叫做程序准备阶段,该阶段创建变量对象、建立作用域链、确定This指向三件事。

程序执行:执行代码,参数赋值,函数引用,变量赋值等。

变量对象

变量对象是和上下文相关的特殊对象,存储着上下文中的相关数据,以属性/值的方式存储三类数据:

参数对象声明:即arguments对象;参数名作为参数对象属性,属性值默认为undefined。

函数声明:函数名作为属性,函数引用作为属性值;若存在同名属性,覆盖原属性值。

变量声明:变量名作为属性,undefined作为属性值;若存在同名属性(参数属性或者函数属性),不影响原属性值。

变量对象是在执行上下文阶段创建的,将上下文中的相关数据(参数、函数、变量)以一定的规则提升到函数内顶级范围并赋值为默认值,这也就是为什么会存在“变量提升”的概念。

例2:

alert(x); //function

var x=10;

alert(x); //10

x=20;

function x(){};

alert(x); //20

程序进入执行上下文阶段:创建VO,因为变量和函数名一样,保持函数名,即VO只有一个属性:VO = {x:< x reference >},该阶段结束。程序进入执行阶段:第一个alert弹出“function x(){}”,因为x默认为函数x;第二个alert弹出“10”,因为在程序执行阶段对x的值进行了修改(这里明确一点:执行上下文阶段 和 程序执行阶段是两个独立的阶段,虽然都是同一个对象(VO  >  AO),执行阶段仍然会修改对象的值),同样,第三个alert弹出“20”。

例3:

if(true){

var a=1;

}else{

var b=2;

}

alert(a); //1

alert(b); //undefined

例4:

alert(a); //undefined

alert(b); //error:"b"没有定义

b = 10;

var a = 20;

上一篇下一篇

猜你喜欢

热点阅读