用动态函数调用

时间:2016-03-01 10:14:03

标签: javascript

我正在创建一个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() {}
}

2 个答案:

答案 0 :(得分: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]();
    };
})();

这就像创建一个孤立的&#34;全球&#34;范围。

旁注:请勿使用eval。这是非常不安全和缓慢的。它会在某些时候适得其反。

答案 1 :(得分: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