- 全局级别的代码 –– 这个是默许的代码运行环境,1旦代码被载入,引擎最早进入的就是这个环境。
- 函数级别的代码 ––当履行1个函数时,运行函数体中的代码。
- Eval的代码 –– 在Eval函数内运行的代码。
-
进入上下文阶段:产生在函数调用时,但是在履行具体代码之前(比如,对函数参数进行具体化之前)
- 创建作用域链(Scope Chain)
- 创建变量,函数和参数。
- 求”this“的值。
-
履行代码阶段:
EC={
VO:{},this:{},Scope:{ }
}
ECS=[局部EC,全局EC];
(function foo(i) {
if (i === 3) {
return
}
else {
foo(++i)
}
}(0))
- 单线程。
- 同步履行。
- 1个全局上下文。
- 无穷制函数上下文。
- 每次函数被调用创建新的履行上下文,包括调用自己。
VO: {
// 上下文中的数据 ( 函数形参(function arguments), 函数声明(FD),变量声明(var))
}
VO(functionContext) === AO;
AO = {
arguments: {
callee:,length:,properties-indexes:
}
};
function f(){
}
- 初始化作用域链:
- 创建变量对象:
- 创建arguments对象,检查上下文,初始化参数名称和值并创建援用的复制。
- 扫描上下文的函数声明:为发现的每个函数,在变量对象上创建1个属性(确切的说是函数的名字),其有1个指向函数在内存中的援用。如果函数的名字已存在,援用指针将被重写。
- 扫面上下文的变量声明:为发现的每一个变量声明,在变量对象上创建1个属性——就是变量的名字,并且将变量的值初始化为undefined,如果变量的名字已在变量对象里存在,将不会进行任何操作并继续扫描。
- 求出上下文内部“this”的值。
function foo(i) {
var a = ‘hello‘;
var b = function privateB() {
};
function c() {
}
}
foo(22);
fooExecutionContext = {
scopeChain: { ... },variableObject: {
arguments: {
0: 22,length: 1
},i: 22,c: pointer to function c()
a: undefined,b: undefined
},this: { ... }
}
fooExecutionContext = {
scopeChain: { ... },c: pointer to function c()
a: ‘hello‘,b: pointer to function privateB()
},this: { ... }
}
alert(x);
var x = 10;
alert(x);
x = 20;
function x() {};
alert(x);
ECObject={
VO:{
x:<reference to FunctionDeclaration "x">
}
};
ECObject={
VO:{
x:20 //与函数x同名,替换掉,先是10,后变成20
}
};
VO = {};
VO['x'] = <援用了函数声明'x'>
VO['x'] = <值不受影响,还是函数>
VO['x'] = 10;
VO['x'] = 20;
if (true) {
var a = 1;
} else {
var b = 2;
}
alert(a); // 1
alert(b); // undefined,but not "b is not defined"
function test(a,b) {
var c = 10;
function d() {}
var e = function _e() {};
(function x() {});
}
test(10);
testEC={
AO:{
arguments:{
callee:test
length:1,0:10
},a:10,c:undefined,d:<reference to FunctionDeclaration "d">,e:undefined
}
};
testEC={
AO:{
arguments:{
callee:test,length:1,0:10
},c:10,e:<reference to FunctionDeclaration "e">
}
};
(function() {
console.log(typeof foo);
console.log(typeof bar);
var foo = ‘hello‘,bar = function() {
return ‘world‘;
};
function foo() {
return ‘hello‘;
}
}());