2012-11-28 69 views
0

我正在編寫一個庫,並且我用「lib.someFunction();」調用了所有函數。或「lib.someVariable;」。我知道我不應該污染全局命名空間,但我想給我的圖書館的用戶這個選項。我聽說一些圖書館有一個「選項」,如「installLibrary();」將類中的所有函數和變量移動到全局名稱空間。installLibrary,將所有函數移動到全局命名空間

這樣,只有用戶纔會喜歡這樣才能調用「someVariable;」或「someFunction();」直。

不過,我的問題是如何編寫這樣一個函數。有任何想法嗎?

+0

瀏覽器或Node.js?另外,不要這樣做。 – SLaks

+0

這可能並不難。你的代碼結構如何? –

+0

瀏覽器。我有一個'函數庫(){this.var = 5; this.otherVar = 4; this.cool = function(){}} var library = new Library();'。 然後我調用像這樣的函數和變量:'library.cool();'。 –

回答

1

你可以做類似如下:

function Library() { 
    this.var = 5; 
    this.otherVar = 4; 
    this.cool = function(x) { 
     return x + this.otherVar; 
    } 
} 
var library = new Library(); 

(function (lib, context) { 
    for (var prop in lib) { 
     if (lib.hasOwnProperty(prop) && prop) { 
      if (typeof lib[prop] == "function") { 
       context[prop] = function() { 
        return lib[prop].apply(lib, arguments); 
       } 
      } else { 
       context[prop] = lib[prop]; 
      } 
     } 
    } 
}(library, this)); 

但使用比這裏的功能以外的任何其他的提防。如果你這樣做,並嘗試調整全局/窗口命名空間的參數,它們將不會被帶回到你的庫函數中,並且可能不會得到你想要的行爲。例如:

library.cool(3); // 7 
cool(3);   // 7 
otherVar = 10; 
library.cool(3); // 7 
cool(3);   // 7 Still? 
library.otherVar = 10; 
library.cool(3); // 13 
cool(3);   // 13 Finally! 

它沒有這個限制將是你的庫構造函數適用於全球/ window對象的選擇:

Library.call(this); 

與麻煩的是,你不」不要用你的公共API來污染全局範圍,而是用你在本地關閉時可能存儲的任何東西來污染全局範圍。這讓我感到沉重。

如果你的庫使用類似揭示模塊模式的東西,並只公開功能,那麼我認爲第一個非常簡單。但正如其他人所說,這可能並不明智。在最多的情況下,我會提供這個作爲用戶的選擇,但警告它。

1

除了不會污染圖書館的全球空間的明顯原因,我相信你可以做下面的事情。

注:我已經寫了這個,看看我們是否在瀏覽器或節點。您應該能夠在瀏覽器中引用「窗口」,在全局名稱空間中引用節點中的「全局」。

var scope = (typeof window !== 'undefined' ? window : global); 
scope.someVariable = true; 
scope.someFunction = function() { }; 

// Essentially, this is the same as: 
window.someFunction = function() { }; 
// or 
global.someFunction = function() { };