作用域是 JavaScript 最重要的概念之一,说简单也简单,说难也难。
下面是在学习的过程中总结出来的一点东西。
简单的说,作用域就是变量与函数的可访问范围。
在 JavaScript 中,变量的作用域有全局作用域和局部作用域两种。
要注意:
- 全局变量的作用域是全局性的,即在整个 Javascript 程序中,全局变量作用处处都存在。定义在 "script" 块中,在 "function" 函数外。
- 局部变量的作用域是局部性的,在函数内部或函数参数时定义,作用范围是从函数开始到结尾,即在{}里。
1. 全局变量
作用域的方式:
<script>
var str1 = "hello1"; //定义一个全局变量,实际上是一个variable
str2 = "hello2"; //定义一个全局变量,实际上是在global下创建一个property
window.str3 = "hello3"; //定义一个全局变量
function func(){
var str4 = "hello4"; //定义一个局部变量
str5 = "hello5"; //定义一个全局变量
}
</script>
for in window 判断是否是全局变量
function Write(str){ //封装了 document.write();
document.write(str + '<br />');
}
for(w in window){
if(w == 'str1' || w =='str2' || w == 'str3' || w == 'str4' || w == 'str5'){
Write(w);
}
}
由此说明,定义全局变量的几种方式,还是有点区别的,它们会因游览器内核不同,而被识别为全局变量也不同。
2. 全局变量的问题
Javascript总是在不知不觉中就出人意料地创建了全局变量。就像:
function func(){
var a = b = 0;
//. . .
}
在这里,你可能想定义两个局部变量,但是代码却是 a 是局部变量,b 是全局变量。原因很简单,由于操作符的优先级是从右到左的,就像。
var a = ( b = 0 );
改为:
var a, b;
a = b = 0;
如果对链式赋值所有变量都进行了声明,就不会创建出不期待的全局变量。
3. 局部变量的问题
先来看看,下面的代码:
<script>
var str = "我是妹子";
(function func(){
var str = "我不是妹子";
Write(str);
})();
Write(str);
</script>
可以看出:
- 在函数内部,局部变量的优先级比同名的全局变量优先级要高;
- 如果存在与全局变量名称相同的局部变量(包括参数),那么该全局变量将不再起作用。
- 局部变量的生存域仅在函数体里,出了函数体,它就不存在了。
就像:
<script>
(function func(){
var str = "我不是妹子";
Write(str);
})();
Write(str);
</script>
第二句 Write(str); 没有东西输出。
4. 变量释放时的问题
先来看看,下面的代码:
<script>
var a = 1; //全局变量
window.b = 2; //全局变量
delete a;
delete b;
Write(typeof a);
Write(typeof b);
(function func(){
var c = 3; //局部变量
d = 4; //全局变量
delete c;
delete d;
Write(typeof c);
Write(typeof d);
})();
</script>
可以看出:
- 使用 var 创建的变量不能使用 delete 释放内存。
- 不使用 var 创建的变量可以使用 delete 释放内存。
5. 零散变量的问题
Javascript允许在函数的任意地方声明多个变量,无论在哪里声明,效果都等同于在函数顶部进行声明。就像:
<script>
var str = "我是妹子";
(function func(){
Write(str);
var str = "我不是妹子";
Write(str);
})();
</script>
为什么不是: 我是妹子 和 我不是妹子?
原因很简单:对JavaScript而言,只要变量是在同一个范围(函数)里,就视为已经声明,哪怕是在变量声明前就使用。上面的代码相当于:
<script>
var str = "我是妹子";
(function func(){
var str; //系统自动赋值为 str = undefined
Write(str);
var str = "我不是妹子";
Write(str);
})();
</script>
总的来说:
1. 要清楚在哪个地方声明定义的是 全局变量 还是 局部变量 。
2. 全局变量所带来的 bug 问题非常多,可能很偶然的把代码放到其他页面里,把新页面的同名变量给覆盖,造成隐藏的 bug 。最好尽量少用全局变量。
3. 不应使用带 var 的链式赋值,声明变量最好带 var 。
4. 在函数体内定义变量时,最好把变量放在顶部。为了防止出现变量在定义前就被使用的逻辑错误。
热门评论
谢谢楼主分享,辛苦了!
楼主。 班门弄斧。