变量对象的创建,依次经历了以下几个过程。
- 建立arguments对象。检查当前上下文中的参数,建立该对象下的属性与属性值。
- 检查当前上下文的函数声明,也就是使用function关键字声明的函数。在变量对象中以函数名建立一个属性,属性值为指向该函数所在内存地址的引用。如果函数名的属性已经存在,那么该属性将会被新的引用所覆盖。
- 检查当前上下文中的变量声明,每找到一个变量声明,就在变量对象中以变量名建立一个属性,属性值为undefined。如果该变量名的属性已经存在,为了防止同名的函数被修改为undefined,则会直接跳过,原属性值不会被修改。
demo1:
console.log(testOne); // function testOne() { console.log('testOne') }
function testOne() { console.log('testOne') }
var testOne = 100;
console.log(testOne); // 100
执行过程:
// 首先将所有函数声明放入变量对象中
function testOne() { console.log('testOne') }
// 其次将所有变量声明放入变量对象中,但是因为testOne已经存在同名函数,因此此时会跳过undefined的赋值
// var testOne;
// 然后开始执行阶段代码的执行
console.log(testOne); // function testOne() { console.log('testOne') }
testOne= 100;
console.log(testOne); // 100
demo2:
function testTwo() {
console.log(a);//undefined
console.log(foo());//2
var a = 1;
function foo() {
return 2;
}
}
testTwo();
//上述代码执行顺序
function testTwo() {
function foo() {
return 2;
}
var a;
console.log(a);
console.log(foo());
a = 1;
}
testTwo();
demo3:
function testTree() {
console.log(foo);//function foo() { return 'hello'; }
console.log(bar);//undefined
var foo = 'Hello';
console.log(foo);//Hello
var bar = function () {
return 'world';
}
console.log(bar);//function () {return 'world';}
function foo() {
return 'hello';
}
}
testTree();
//上述代码执行顺序
function testTree() {
function foo() {
return 'hello';
}
var foo,bar;
console.log(foo);
console.log(bar);
foo = 'Hello';
bar = function () {
return 'world';
}
console.log(foo);
console.log(bar);
}
testTree();
网友评论