Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/459.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在javascript中动态调用本地函数_Javascript_Closures_Scope - Fatal编程技术网

在javascript中动态调用本地函数

在javascript中动态调用本地函数,javascript,closures,scope,Javascript,Closures,Scope,关于动态地按名称调用函数,有很多类似的问题。但是,我无法找到解决我的特定问题的方法,在闭包中包含本地函数,而不向对象的公共接口公开这些函数 让我们看看一些代码(这是一个虚构的例子) 这不起作用,因为“This”是MyObject,并且本地函数没有公开。 另外,在尝试调用之前,我希望能够检查该函数是否存在。 例如 我真的不知道如何继续,除了将我的私有函数公开给公共接口之外,一切都正常 obj.privateMethod1 = function(arg) { //do something wit

关于动态地按名称调用函数,有很多类似的问题。但是,我无法找到解决我的特定问题的方法,在闭包中包含本地函数,而不向对象的公共接口公开这些函数

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

这不起作用,因为“This”是MyObject,并且本地函数没有公开。 另外,在尝试调用之前,我希望能够检查该函数是否存在。 例如

我真的不知道如何继续,除了将我的私有函数公开给公共接口之外,一切都正常

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

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

我的点子快用完了。非常感谢您的帮助和建议。

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

(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);
(函数(窗口,$){
//使用“var MyObject=”而不是“MyObject=”!!否则,您将分配
//对象指向MyVar的最近父声明,而不是本地声明!
变量MyObject=(函数($){
var obj={};

var local={};//私有函数是局部变量,不是任何对象的一部分。因此,用于访问属性的
[…]
符号永远不会起作用,因为没有私有函数是其属性的对象

相反,您可以创建两个对象:
private
public

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

不能在定义这些函数的范围之外调用这些函数,这是javascript的一个基本部分,事实上,也是所有编程语言的一个基本部分

调用这些函数的唯一方法是将它们公开。但是,可以采用基于约定的方法。下划线前缀相当普遍,通常理解为“不打算作为公共函数调用”,例如:


我很惊讶错误的答案被标记为已接受。实际上,您可以通过字符串获得对局部变量的引用。只需使用
eval

(函数(窗口,$){
MyObject=(函数($){
var obj={};
obj.publicMethod=函数(数字,其他参数){
//获取对局部变量的引用
var方法=评估(“私有方法”+数字);
//你想怎么做就怎么做
方法。应用(此[otherarg]);
};
var privateMethod1=函数(arg){
//用arg做点什么
};
var privateMethod2=函数(arg){
//用arg做些别的事情
};
返回obj;
})($);
window.MyObject=MyObject;
})(窗口,jQuery);

实际上,这段代码非常糟糕,在99.9%的情况下你不应该使用
eval
。但是你必须知道它是如何工作的以及你可以用它做什么。我自己也有一些非常特殊的情况,当需要使用
eval
时。

假设你只需要调用几个函数,你可以创建自己的Window版本来使用它调用以下函数:

var myFuncs = {
    'foo': foo,
    'bar': bar
};
然后在代码中:

var s = 'foo';
myFuncs[s]();
只需确保在将函数添加到对象时定义了这些函数。在加载时函数不存在的模块中,可以在初始化模块时添加这些函数:

var myFuncs = {};
var init = function(){
    myFuncs['foo'] = foo;
    myFuncs['bar'] = bar;
}

这么直截了当地说……我一直在唱咒语,以至于忘了它的意思。这个Q很老了,但是,公认的答案有什么问题?它被广泛认为是javascript对象上公共/私有方法的正确方法。实际上,我的抱怨是“你不能通过字符串获得对局部变量的引用”。这不是真的,你可以。正如我所写的:使用
eval
是非常糟糕的做法,但你必须知道如何使用它。使用
eval
你可以通过字符串访问局部变量。我认为这个答案可能误导其他javascript用户。答案的另一部分呢?它是正确的(虽然我认为@pimvdb variant稍微好一点,但这并不重要)。为了澄清这一点,您不再需要别名声明
var privateMethodX
,因为它们是
local
的一部分;我假设它们仍然在本例中进行比较。
var myFuncs = {
    'foo': foo,
    'bar': bar
};
var s = 'foo';
myFuncs[s]();
var myFuncs = {};
var init = function(){
    myFuncs['foo'] = foo;
    myFuncs['bar'] = bar;
}