使用call或apply调用闭包中的函数?

时间:2017-06-29 12:35:36

标签: javascript

假设我有一个松散的扩充闭包,其中包含一些我想要访问的函数[极其简化]

var Process = (function(Process,$){
    _thing1 = function(a,b,c) {
         return a + b + c;
    }
    _thing2 = function(a,b,c) {
         return $(a).html(b + c);
    }
    return {
       Fred: {
          Add: _thing1
       },
       Bob: {
          Add: _thing2
       }
     }
}(Process || {},jQuery));

我可以直接调用该函数

var foo = Process.Fred.Add(1,2,3);

如果我想要调用的函数名的对象中有一个字符串表示形式和一些参数,我该如何调用它?

var data = {
    "function": "Process.Fred.Add",
    "params": [1,2,3]
}

我无法使用data.function.apply(data.function.params),因为它会导致类型错误。

2 个答案:

答案 0 :(得分:2)

如果Process在全局范围内,您可以遍历树以获取对方法的引用,以便您可以执行它。

var Process = (function(Process, $) {
  _thing1 = function(a, b, c) {
    return a + b + c;
  }
  _thing2 = function(a, b, c) {
    return $(a).html(b + c);
  }
  return {
    Fred: {
      Add: _thing1
    },
    Bob: {
      Add: _thing2
    }
  }
}(Process || {}, jQuery));

var data = {
  "function": "Process.Fred.Add",
  "params": [1, 2, 3]
}

var result = data.function.split(/\./g)         //break up string into pieces
               .reduce((o, k) => o[k], window)  //walk the tree to get method reference
                 .apply(this, data.params);     //execute the method with the parameters
console.log(result)
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

如果它不在全球范围内,则需要将Process放在可以引用的某个地方。

EG:一个对象

var myStuff = { "Process: : {} }

比减少线

... reduce((o,k)=&gt; o [k],myStuff)

答案 1 :(得分:0)

您需要先评估字符串:

eval(data.function).apply(data.function.params)

但是don't use eval needlesslyeval is evil