贤心按:全局变量的滥用在多前端开发人员的合作中,诟病显得尤为突出。所以在编码过程中,良好的规范是成为一个team成员的必修课。本文试图详细地让你认识何为全局变量,并给出了避免污染的解决方案,譬如命令空间,比如函数形成的闭包体等等。当然,作者并没有特别去介绍全局污染带来的问题,但作为你,可以尝试去深入思考。
定义全局变量有3种方式:
1、在任何函数外面直接执行var语句。
var f = 'value';
2、直接添加一个属性到全局对象上。全局对象是所有全局变量的容器。在Web浏览器中,全局对象名为window。
window.f = 'value';
3、直接使用未经声明的变量,以这种方式定义的全局变量被称为隐式的全局变量。
f = 'value';
为方便初学者在使用前无须声明变量而有意设计了隐式的全局变量,然而不幸的是忘记声明变量成了一个非常普遍的现象。JavaScript的策略是让那些被忘记预先声明的变量成为全局变量,这导致在程序中查找Bug变得非常困难。
JavaScript语言最为糟糕的就是它对全局变量的依赖性。全局变量就是在所有作用域中都可见的变量。全局变量在很小的程序中可能会带来方便,但随着程序越来越大,它很快变得难以处理。因为一个全局变量可以被程序的任何部分在任意时间改变,使得程序的行为被极大地复杂化。在程序中使用全局变量降低了程序的可靠性。
全局变量使在同一个程序中运行独立的子程序变得更难。如果某些全局变量的名称与子程序中的变量名称相同,那么它们将会相互冲突并可能导致程序无法运行,而且通常还使程序难以调试。
实际上,这些全局变量削弱了程序的灵活性,应该避免使用全局变量。努力减少使用全局变量的方法:在应用程序中创建唯一一个全局变量,并定义该变量为当前应用的容器。
var My = {};
My.name = {
"first-name" : " first ",
"last-name" : " last "
};
My.work = {
number : 123,
one : {
name : " one ",
time : "2012-9-14 12:55",
city : "beijing"
},
two : {
name : "two",
time : "2012-9-12 12:42",
city : "shanghai"
}
};
只要把多个全局变量都追加在一个名称空间下,将显著降低与其他应用程序产生冲突的概率,应用程序也会变得更容易阅读,因为My.work指向的是顶层结构。当然也可以使用闭包体将信息隐藏,它是另一种有效减少“全局污染”的方法。
在编程语言中,作用域控制着变量与参数的可见性及生命周期。这为程序开发提供了一个重要的帮助,因为它减少了名称冲突,并且提供了自动内存管理。
var foo = function() {
var a = 1, b = 2;
var bar = function() {
var b = 3, c = 4; // a=1, b =3, c=4
a += b + c; // a=8, b =3, c=4
}; // a=1, b =2, c=undefined
bar(); // a=21, b =2, c=undefined
};
大多数采用C语言语法的语言都拥有块级作用域。对于一个代码块,即包括在一对大括号中的语句,其中定义的所有变量在代码块的外部是不可见的。定义在代码块中的变量在代码块执行结束后会被释放掉。但是,对于JavaScript语言来说,虽然该语言支持代码块的语法形式,但是它并不支持块级作用域。
JavaScript支持函数作用域,定义在函数中的参数和变量在函数外部是不可见的,并且在一个函数中的任何位置定义的变量在该函数中的任何地方都可见。
其他主流编程语言都推荐尽可能迟地声明变量,但是在JavaScript中就不能够这样,因为它缺少块级作用域,最好的做法是在函数体的顶部声明函数中可能用到的所有变量。