代码改变世界

JavaScript基础尽量少使用全局变量(001)

2014-09-12 23:14  Bryran  阅读(506)  评论(0编辑  收藏  举报

Pattern意思是模式,好的编码习惯经过多次实践的应用就会形成模式,而反模式(Anti-Pattern)则是不好的编码习惯。了解 JavaScript模式之前,先来看看Anti-pattern的例子。Javascript使用函数(function)来管理变量的作用域 (scope)。定义在函数体内部的变量是局部变量,而其它定义在函数体外的变量是全局变量。全局变量在Javascript中通常是不应该使用的。如:

myglobal = "hello"; // antipattern,因为这是个全局变量
console.log(myglobal); // "hello"
console.log(window.myglobal); // "hello"
console.log(window["myglobal"]); // "hello"
console.log(this.myglobal); // "hello"

 全局变量的问题有很多。因为全局变量是被页面中所有Javascript代码所共享的,因此很容易导致变量冲突。比如当你使用一些第三方的 Javascript插件,如Jquery,YUI,ExtJS,或你同事写的一小段JS代码;如果这些代码里有一些全局变量与你程序中的全局变量在命名上冲突了,就会导致一些意想不到的情况出现。
但是Javascript是非常灵活的语言,有时候你会在不经意间让你的变量”变成“全局的:

function sum(x, y) {
    // antipattern: implied global
    result = x + y;
    return result;
}

 上面的代码里,result在sum函数中第一次出现,但由于声名时没有使用var,所以它是一个implied global,隐式地声名为了一个全局变量。所以每次声名变量,我们应该都使用var关键字,这样做一来可以了解变量是在哪里定义的,二来也保证它不会被隐式声名为全局变量:

function sum(x, y) {
     var result = x + y;
     return result;
}

 另外,我们还应该避免使用连续的声名,在下面的例子里,a是局部变量,而b则是全局的(这和一般人的认知可能会不相同)。

// antipattern, do not use
function foo() {
      var a = b = 0;  //等同于var a = (b = 0);使得b“变成”了全局变量
      // ...
}

 所以我们应该这样做:

function foo() {
      var a, b;
      // ...
      a = b = 0; // both local
}

 最后,隐式全局变量(不用var声名出来的)和显式全局变量(用var声名出来的)在Javascript中还是有区别的。隐式全局变量其实是全局对象 (Global Object,Javascript中自带的一个对象)的属性,是可以手动删除的,而显式的则不可以删除。看下面的例子:

// define three globals
var global_var = 1; //显式全局
global_novar = 2; // antipattern,隐式全局

(function () {
global_fromfunc = 3; // antipattern,隐式全局
}());

// attempt to delete
delete global_var; // false
delete global_novar; // true
delete global_fromfunc; // true

// test the deletion
typeof global_var; // "number"
typeof global_novar; // "undefined"
typeof global_fromfunc; // "undefined"

 顺便说一下如何在Javascript里访问全局对象(Global Object):

var global = (function () {
      return this;
}());