JavaScript的声明提前:JavaScript函数里声明的所有变量都被“提前”至函数体的顶部。
在看例子之前我们先说一下变量的作用域:
全局变量作用域:在JavaScript代码的任何地方都可以用。
局部变量作用域:局部变量是在函数内部声明的,只在函数内部可以用。
在函数体内部,局部变量的优先级高于同名的全局变量。如果在函数内声明的一个局部变量或者函数参数中带有的变量和全局变量重名,全局变量就被局部变量遮盖。
意思是在函数中先找这个变量在函数中有没有定义,如果有定义,则用的是函数中定义的局部变量,若没有在函数中找到,则在全局里找。
此时我们看例子:
<html>
<head>
</head>
<body>
</body>
</html>
<script>
var scope="global";
function f(){
alert(scope);//undefined
var scope="local";
alert(scope);//loacl
}
f();
</script>
学过java语言的同学可能会认为第一个alert(scope);的结果是“global”,但是运行上段的代码,第一个alert(scope);的结果却是undefined,这是为什么呢?
我们在f()方法里找scope变量是不是在函数体中定义过的,在函数体中找到了,但是下面一行才对scope局部变量赋值,这里会输出undefined,
是相当于在f()函数体的开始就将f()函数里声明的所有变量都被“提前”至函数体的顶部,即在开始时先var scope;了。
上面的代码相当于:
<html>
<head>
</head>
<body>
</body>
</html>
<script>
var scope="global";
function f(){
var scope;
alert(scope);//undefined
scope="local";
alert(scope);//loacl
}
f();
</script>
JavaScript的声明提前导致了JavaScript的函数的作用域与java语言的作用域的不同。
学过Java的同学知道在一个方法里写一个for循环,for循环里定义的变量只能在for循环里使用,出了for循环,就不能用了。
但是JavaScript的函数的作用域指的是:在函数体内声明的所有变量在函数体内始终是可见的。不管这个变量是在函数的什么时候地方声明的。
看下面的例子:
<html>
<head>
</head>
<body>
</body>
</html>
<script>
function test(o){
var i=0;
if(typeof(o) == "object"){
var j=2;
for(var k=0;k<10;k++){
alert("["+k+"]"+k);
alert("j---"+j);//2
}
alert("---"+k);//10
}
alert("===="+j);//2
}
var n=new Number(3);
test(n);
</script>
运行后,alert("["+k+"]"+k);的k输出0-9的值, alert("j---"+j);的j的值是2,
alert("---"+k);的k是10,上面的 “JavaScript的函数声明提前” 理解的话,就知道了:在函数里声明的变量都被提前到函数体的开头声明了。
alert("===="+j);的j是2,和上面的解释一样。
这个例子相当于:
<html>
<head>
</head>
<body>
</body>
</html>
<script>
function test(o){
var i=0;
var j;
var k;
if(typeof(o) == "object"){
j=2;
for(k=0;k<10;k++){
alert("["+k+"]"+k);
alert("j---"+j);
}
alert("---"+k);//10
}
alert("===="+j);//2
}
var n=new Number(3);
test(n);
</script>
test(o)函数中有个if判断,因此,如果是下面的情况呢:
<html>
<head>
</head>
<body>
</body>
</html>
<script>
function test(o){
var i=0;
if(typeof(o) == "object"){
var j=2;
for(var k=0;k<10;k++){
alert("["+k+"]"+k);
}
alert("---"+k);
}
alert("===="+j);//undefined
}
test(3);
</script>
此时if()里面的不会执行,就直接alert("===="+j);,结果j是undefined。因为JavaScript的声明提前原因,所以这里在开头相当定义了var j;但是后面没有给j初始化,所以alert("===="+j);,结果j是undefined。