学习来源:http://blog.csdn.net/zyz511919766/article/details/7276089
function作用域中的全局变量和局部变量
例:
<script>
var a = 1;
function test() {
alert(a); //输出undefined
a = 2;
var a;
alert(a); //输出 2
}
alert(a); //输出 1
test();
</script>
function中的 第一个alert(a) 和 a =2 中的a并不是全局变量中的a,而是后面声明的var a;
变量声明语句和函数声明语句都会提前。
js的变量范围是根据方法块来划分的(也就是function的大括号{ })。而for、while、if块并不是作用域的划分标准。
例:
<script>
function test2(){
alert (i); // 输出underfined i未赋值,并不是未声明
for(var i=0;i<3;i++){
alert(i); // 输出0、1、2, 当i=3时跳出循环
}
alert(i); // 输出3 已跳出for范围外,但i的值仍然保留为3
while(true){
var j = 1;
break;
}
alert(j); // 输出1 已跳出while范围外 但j的值仍然保留为1
if(true){
var k = 1;
}
alert(k); // 输出1 已跳出if范围外 但k的值仍然保留为1
}
test2();
</script>
一道面试题:
alert(a); //function a(){alert(4);}
var a = 1;
alert(a); //1
function a(){alert(2);}
alert(a); //1
var a = 3;
alert(a); //3
function a(){alert(4);}
alert(a); //3
预解析时 函数覆盖var声明 同级后者覆盖前者
所以一开始预解析(寻找var 函数 参数)时 就只剩 function a(){alert(4);}
预解析完,开始逐行解析代码,表达式(有=号)可以覆盖预解析里的值
var a = 1;
function fn1(){
alert(a);// undefined
var a = 2;
}
fn1();
alert(a);// 1
var a = 1;
function fn1(){
alert(a);// 1
a = 2;
}
fn1();
alert(a);// 2
var a = 1;
function fn1(a){
alert(a);// undefined
a = 2;
}
fn1();
alert(a);// 1
var a = 1;
function fn1(a){
alert(a);// 1
a = 2;
}
fn1(a);
alert(a);// 1
总结:
1)先预解析 从上到下(以作用域为单位)
寻找var 函数 参数 找到后 赋为undefined
2)再逐行解析代码
碰见找到过的 如果是表达式(或调用函数时的参数) 则可覆盖预解析里原先的值
1)2)两步先外作用域 逐行时要执行函数 再在函数的内作用域 再重新进行局部的1)2)步骤
局部的预解析若未找到var 函数 参数中任何一个 则在逐行解析的时候有需求 可向外寻找同名。
注意:火狐 在if for语句定义全局函数 无法预解析这些全局函数