2016-03-01 118 views
0

我創建一個JS「庫」文件,但我想封裝它在它的全部對象中,以避免污染,其中包括文件創建JS庫,動態函數調用

的頁面的命名空間扭曲這是在圖書館內的功能,我需要通過名稱稱爲庫內的其他功能,例如使用window[]

下面的代碼只是一個示例,實際上有幾百個函數可以按名稱調用。這是由於我無法獲得window[]來引用函數,這是由什麼引起的?

我已經試過了,在主機頁面:

<script src= "mylib.js"></script> 

var oMyLib = new cMyLib(); //there will only ever be one 'instance' of this 

在mylib.js一切都包含在一個功能:

function cMyLib() { 

    this.doStuff = function() { 
     someFunc(this); //call another function in the lib 
    } 
    // I tried it with prototypes also 
    // cMyLib.prototype.doStuff = function() { 
    //  someFunc(); 
    // } 


    function someFunc(that) { 
     var s='anotherFunc1' 
     var f = window[s]; //undefined! 
     f(); 
     s='anotherFunc2' 
     f=window[s]; 
     f(); 
    } 

    function anotherFunc1() {} 
    function anotherFunc2() {} 
} 
+1

只有全局函數顯示爲'window'的屬性,並且你不想這樣做(因爲這會污染名稱空間)。爲什麼你認爲你需要調用'window ['anotherFunc1']'那樣的? – Alnitak

+0

riiight,這使得完整的感覺,拍額頭,我現在想着如果我不想使用eval,我不認爲實際上是壞的,我可以使數字引用的函數的數組。它的處理器模擬器,所以功能是指令,直接等於數字無論如何.. – martinc

+0

你不能給一個函數一個數字的名字,但你可以做'this.insns = {}; this.insns [0x4c] =函數lda(...)' – Alnitak

回答

0

您希望通過名稱引用(或實際數量,根據您的評論)應該是對象的一部分,並通過window不訪問,如功能:

function cMyLib() { 
    // allow call without new 
    if (! (this instanceof cMyLib)) { 
     return new cMyLib(); 
    } 

    // enforce singleton 
    if (this.constructor.singleton) { 
     return this.constructor.singleton; 
    } else { 
     Object.defineProperty(this.constructor, 'singleton', { 
      value: this 
     }); 
    } 

    // instruction array (no need to expose via `this`) 
    var insn = []; 
    insn[0x4c] = function lda_immediate() { ... } 

    // instruction execution 
    this.step = function() { 
     var opcode = memory[pc++]; 
     if (opcode in insn) { 
      // `.call` ensures `this` is set inside the instruction fn. 
      insn[opcode].call(this); 
     } else { 
      hcf(); 
     } 
    } 
} 

注意多餘的東西在頂部 - 便利代碼以確保只有一個cMyLib可以存在。

0

只要功能是在父範圍可以只直接參考,即

function someFunc(that) { 
    anotherFunc1(); 
}; 

將簡單地工作。

另一件事是,傳統的方式做,這是自調用匿名函數包裹的一切,即

(function() { 
    function anotherFunc1() {}; 
    function anotherFunc2() {}; 
    this.cMyLib = function() { ... }; 
})(); 

但是你的做法是好的,以及。

如果你想通過動態名字來稱呼你的函數,那麼你可以將它們存儲在一個頂層對象:

(function() { 
    var my_functions = { 
     anotherFunc1: function() {}, 
     anotherFunc2: function() {} 
    }; 
    this.cMyLib = function() { 
     var name = 'anotherFunc1'; 
     my_functions[name](); 
    }; 
})(); 

這就像建立一個孤立的「全局」範圍。

備註:請勿使用eval。這是非常不安全和緩慢的。它會在某個時候對你起反作用。

+0

非常感謝,事情是我不能直接參考函數,因爲會有幾百個。它的處理器模擬器,每個指令都有一個函數。 eval引誘我 – martinc

+0

@martinc我不明白你的問題。即使有數百萬人,那又如何?只要函數在父範圍內,您可以引用它。如果你想動態引用它(比如通過動態生成的名字),然後把它們放在一個對象/字典中。 – freakish

+0

@martinc查看更新。 – freakish