在js中,var声明的变量,如果在方法中声明,那么就是局部变量,如果在全局声明则是全局变量。
如果变量没有通过var声明,直接赋值,则自动默认为全局变量。
ps:方法块中才是局部变量范围,具体指函数的{ }内,循环、判断并不是作用域的判断标准。
在js执行之前,js会自动分析所有代码的声明部分,判断各个变量的声明。具体看例二和例三。
一、全局作用域(全局作用域就是在整个代码中都能访问的对象)
第一种全局作用域是最外面定义的变量
var toDay = "Tuesday";
function func() {
var yesterday = "Monday";
function func2() {
console.log(yesterday);
}
func2()
}
alert(toDay);
{#提示Tuesday#}
alert(yesterday);
{#报错#}
func();
{#打印Monday#}
func2();
{#报错#}
1,最外面声明的变量,方法内都可以调用。
2,外面函数声明的变量,里面的函数可以调用。
3,外面不能调用函数里面声明的变量。
4,外面不能调用函数里面的函数。
第二种是不写var的变量
function func() {
toDay = "Tuesday";
var yesterday = "Monday";
alert(toDay)
}
func();
{#执行函数,提示Tuesday#}
alert(toDay);
{#提示Tuesday#}
alert(yesterday);
{#报错#}
没有定义,直接赋值,自动声明为全局变量。
还有一种,所有window对象的属性拥有全局作用域。
一般情况下,window对象的内置属性都拥有全局作用域,例如window.name、window.location、window.top等等。
二、局部变量(在函数内部,当局部变量与全局变量重名时,局部变量优先级高于全局变量,但不会在内存区域中覆盖全局变量:)
简单说就是,局部变量在局部范围内会覆盖全局变量,但离开局部变量范围,会变回全局变量。
例一
<script type="text/javascript">
var a = "Hello";
function test(){
var a;
alert(a); //未定义,因为方法内的声明没有赋值
a = "World";
alert(a); //World
}
</script>
执行结果是未定义和world
例一中,由于在函数中声明了a,所以这个a是局部变量,然而没有赋值,直接alert,所以结果会报未定义。
例二
<script>
var a = "Hello";
function test(){
alert(a); //Hello
a = "World";
alert(a); //World
}
test();
alert(a) //Hello
</script>
执行结果为Hello World
在方法test中,首先alert(a); 由于a在方法块中也没有var声明,所以直接找外面的全局变量a=”Hello”.
后面由于在次全局变量赋值为world,所以第二次alert就变成了world,需要注意的是,此时,外面的全局变量已经被覆盖为world了。
所以即便在方法外面执行alert也是world。
例三:
<script>
var a =1;
function test(){
alert(a); //未定义
a=4;
alert(a); //4
var a;
alert(a); //4,上面第五行已经赋值了
}
test();
alert(a); //1
</script>
例三需要注意的是,js程序执行前会先找到所有声明的变量,test方法中,第一个alert(第四行),
这里js程序执行前不会去找方法外面声明的a=1,而是先找方法块内{ } var声明的a,但是此时a还没有被赋值,所以结果是未定义,所以如果此时将函数内的var a删掉,
第四行的代码就会去找方法外面声明的var a=1了。
在最后,alert(a),这次还是找到的第二行的var a=1,因为test方法内的局部变量只能影响在test函数内,并不能影响全局范围。
总结:
JavaScript通过函数管理作用域。
局部变量:在函数内部声明的变量是局部变量,只能在这个函数内部使用,函数外部不可用。
全局变量:在任何函数外面声明的变量;或是未经声明在函数内部直接简单使用的变量。
全局对象:每个JavaScript环境有一个全局对象,当你在适当的地方使用this的时候可以访问到。你创建的每一个全局变量都是这个全局对象的属性或数组元素。在浏览器中,为方便起见,该全局对象有个附加属性叫做window,此window(通常)指向该全局对象本身。