2012年10月30日 星期二

[宅] javascript筆記(8) - 全域變數&匿名函數

最近在PTT ajax版看到一篇非常不錯的筆記,正好把之前雜亂無章的理解給重新整理了一遍。
原文:http://disp.cc/b/11-4CrK (Knuckles@PTT)

使用全域變數時,由於要往上查找全域,造成效能低落,所以應盡量避免大量使用。
文中作者提到匿名變數的方法:
(function(x){ /*...*/ })(x);
自己寫lib時也曾用這個方法來寫。雖然在匿名函式外看不到裡面所定義的function和變數,但是可以在匿名函式內綁定function和外部觸發事件。也可以將匿名函式裡特定物件設為全域變數,由於scope的關係,外面看的到這個object,這個object也看得到匿名函式裡的其他function和變數。我們以ember.js開頭的一小段程式碼來做了解:
(function() {
  ...
  /**
  @class Ember
  */
  if ('undefined' === typeof Ember) {
    Ember = {};

    if ('undefined' !== typeof window) {
      window.Em = window.Ember = Em = Ember;
    }
  }
  ...
})();
當一個全域變數被定義時,等於是加入到window這個object底下。所以Ember={}跟window.Ember={}是一樣的。
而Ember這個object可能有很多function,例如Ember.deprecate,就可以在全域被看到。但如果Ember.deprecate需要使用一些varible或function,這些東西都必須放在Ember所被定義的匿名函式裡。

從Ember的寫法也能看出來,當include一個lib進來的時候,通常會定義一個特定名稱的Object再將相關的變數及函式都塞在這個Object底下,避免一不小心就重複命名了。