在javascript中动态调用本地函数

Rob*_*Rob 4 javascript closures scope

关于按名称动态调用函数有很多类似的问题.但是,我找不到我的特定问题的解决方案,其中我在闭包内部有本地函数,而不将函数暴露给我的对象的公共接口.

让我们看一些代码(这是一个虚构的例子)......

(function(window,$) {

  MyObject = (function($) {
    var obj = {};
    obj.publicMethod = function(number,otherarg) {
      this['privateMethod'+number].apply(this,[otherarg]);
    };

    var privateMethod1 = function(arg) {
      //do something with arg
    };

    var privateMethod2 = function(arg) {
      //do something else with arg
    };

    return obj;
  })($);

  window.MyObject = MyObject;
})(window,jQuery);
Run Code Online (Sandbox Code Playgroud)

这不起作用,因为"this"是MyObject,并且不公开本地函数.此外,我希望能够在尝试调用之前检查函数是否存在.例如.

var func_name = 'privateMethod'+number;
if($.isFunction(this[func_name])) {
  this[func_name].apply(this,[otherarg]);
}
Run Code Online (Sandbox Code Playgroud)

我不确定如何继续进行,除了将我的私有函数暴露给公共接口之外,它一切正常.

obj.privateMethod1 = function(arg) {
  //do something with arg
};

obj.privateMethod2 = function(arg) {
  //do something else with arg
};
Run Code Online (Sandbox Code Playgroud)

我的想法已经不多了.非常感谢您的帮助和建议.

pim*_*vdb 7

私有函数是局部变量,不是任何对象的一部分.因此,[...]访问属性的符号永远不会起作用,因为私有函数没有对象的属性.

相反,你可以制作两个对象:privatepublic:

var public  = {},
    private = {};

public.publicMethod = function(number, otherarg) {
  // `.apply` with a fixed array can be replaced with `.call`
  private['privateMethod' + number].call(this, otherarg);
};

private.privateMethod1 = function(arg) {
  //do something with arg
};

private.privateMethod2 = function(arg) {
  //do something else with arg
};

return public; // expose public, but not private
Run Code Online (Sandbox Code Playgroud)


Rob*_*b W 6

您无法通过字符串获取对局部变量的引用.您必须将本地对象添加到命名空间:

(function(window,$) {
  // Use "var MyObject = " instead of "MyObject = "!! Otherwise, you're assigning
  //  the object to the closest parent declaration of MyVar, instead of locally!
  var MyObject = (function($) {
    var obj = {};
    var local = {};  // <-- Local namespace
    obj.publicMethod = function(number,otherarg) {
      local['privateMethod'+number].call(this, otherarg);
    };

    var privateMethod1 = local.privateMethod1 = function(arg) {
      //do something with arg
    };

    var privateMethod2 = local.privateMethod2 = function(arg) {
      //do something else with arg
    };

    return obj;
  })($);

  window.MyObject = MyObject;
})(window,jQuery);
Run Code Online (Sandbox Code Playgroud)