示例代码如下:
var d = '全局的';
(function(){
alert(d == undefined);//结合步骤4
var d = 123;
})();
(function(a){
var a;
alert(a == 123);//结合步骤1,4;
})(123);
(function(){
alert(d == undefined);//结合步骤4
var d = 123;
})();
(function(a){
var a;
alert(a == 123);//结合步骤1,4;
})(123);
(function(){
alert(typeof a == 'function');//结合步骤2,4;
function a(){} //这句换下面,结果还是一样
var a = 234;
})();
alert(typeof a == 'function');//结合步骤2,4;
function a(){} //这句换下面,结果还是一样
var a = 234;
})();
(function(){
alert(typeof a == 'function');//结合步骤2,4
var a = 234;//这里赋值是在函数初始化完成后执行阶段完成的,因此下面a的类型变成了number
alert(typeof a == 'number');//并没有违反步骤2,4规则,由于这是在执行期间判断的,上面的逻辑已经将a改变了
function a(){}
})();
alert(typeof a == 'function');//结合步骤2,4
var a = 234;//这里赋值是在函数初始化完成后执行阶段完成的,因此下面a的类型变成了number
alert(typeof a == 'number');//并没有违反步骤2,4规则,由于这是在执行期间判断的,上面的逻辑已经将a改变了
function a(){}
})();
函数执行前期初始化变量环境走了如下过程:
1、遍历参数列表,添加到函数变量环境并赋值。
2、遍历函数声明,如果函数变量环境中存在则赋值,不存在则添加并赋值。
3、添加arguments并赋值【这里不同浏览器表现差异较大,并不一定都是这样】
4、遍历函数中所有的变量声明,如果变量环境中存在则不作任何操作,不存在则添加并赋值undefined。
这四个步骤完成后,函数才开始真正执行相关逻辑,所有的赋值语句才开始从上往下生效。
手打累了,不打了,看到这里应该也明白了函数声明提前问题了