简体   繁体   English

通过名称(字符串)在类内部执行私有函数

[英]Execute private function inside the class by its name (string)

At the moment I have simple JavaScript class like this: 目前,我有一个简单的JavaScript类,如下所示:

function MyClass() {

// ... some code ...

this.Create = function() {
  funcName = 'myTestFunc()';
  cTimer = setTimeout(funcName, 1000);
  }

// ... more code ...

var myTestFunc = function() {
  alert ('everything\'s OK!');
  }

// ... more code ...
}

and to test it I'm using this code: 并对其进行测试,我使用以下代码:

x = new MyClass();
x.Create();

I have some troubles to execute this function by it's name. 我很难按其名称执行此功能。 If I put just eval(funcName); 如果我只把eval(funcName); instead of setTimeout call it works fine but can't figure out why it doesn't work this way. 而不是setTimeout调用,它可以正常工作,但无法弄清楚为什么它不能以这种方式工作。

Course, this is part of more complex code but rest of code is irrelevant to this problem. 当然,这是更复杂的代码的一部分,但其余代码与该问题无关。

My question is obvious - How to execute function by its name set as setTimeout function's argument? 我的问题很明显-如何通过将名称设置为setTimeout函数的参数来执行函数? Is it possible? 可能吗?

Note: Making this function public ( this.myTestFunc = ... ) isn't an option! 注意:不能公开此函数( this.myTestFunc = ... )!

Update: 更新:

funcName = "myTestFunc()"; is just an example. 只是一个例子。 In real code it looks like funcName = getRandomEffectFunctionName(); 在实际代码中,它看起来像funcName = getRandomEffectFunctionName(); ! It's just a random value. 这只是一个随机值。

Referring to the update: 参考更新:

Instead of setting: 而不是设置:

 var funcName = "getRandomEffectFunctionNeme()";

Thus, setting a reference to the function's name you should do 因此,设置对函数名称的引用应该

 var funcRef = getRandomEffectFunctionNeme;

And set a reference to the function itself . 并设置对函数本身的引用。 Not only this avoids the issues setTimeout with strings has*. 这不仅避免了带有字符串has *的setTimeout问题。 It also solves your closure issue since your code is structured in such a way the timeout has access to the function itself. 由于代码的结构以超时可以访问函数本身的方式构造,因此它也解决了关闭问题。

In your case, let's assume you have some functions that are filters, for example lowPass highPass and blur . 在您的情况下,我们假设您具有一些过滤器功能,例如lowPass highPassblur In that case, instead of choosing a function name we would be choosing a function. 在这种情况下,我们将选择功能而不是选择功能名称

First, we store these functions in an array: 首先,我们将这些函数存储在数组中:

var filters = [lowPass,highPass,blur];

In JavaScript, functions are first-class objects, you can pass them around just like other objects. 在JavaScript中,函数是一流的对象,您可以像其他对象一样传递它们。

Next, we'll get a random number 接下来,我们将获得一个随机数

var chosen = Math.floor(Math.random()*3);//get a random number between 0 and 2

Finally, we'll choose the filter and invoke it 最后,我们将选择过滤器并调用它

var filter = filters[chosen];
setTimeout(filter,1000);

( * just try debugging it, it basically invokes the compiler whenever ran and is painfully slow) (*只是尝试调试它,它基本上在运行时会调用编译器 ,并且运行缓慢)


You just pass a function to setTimeout as a parameter, rather then a string, setTimeout(myTestFunc,1000) . 您只需将一个函数传递给setTimeout作为参数,而不是字符串setTimeout(myTestFunc,1000)

When calling Create it would have access to it anyway because they are in the same closure. 调用Create时,无论如何都可以访问它,因为它们处于同一闭包中。

NOTE: This solution is only applicable if you can not pass the function name as a function reference , for example if you're integrating with code that is outside your control. 注意:此解决方案仅在您不能将函数名称作为函数引用传递时才适用 ,例如,如果您正在与控件之外的代码集成。 Generally, when possible, you should pass a function reference since in JavaScript, all functions are objects. 通常,在可能的情况下,您应该传递函数引用,因为在JavaScript中,所有函数都是对象。

Assuming that the timeout and the function are in the same closure your code is pretty close. 假设超时和函数在同一个闭包中,则代码非常接近。 The problem is that your eval call executes in the global context because it is in a timer. 问题在于您的eval调用在全局上下文中执行,因为它在计时器中。 This means they are no longer in the same lexical scope. 这意味着它们不再处于相同的词汇范围内。

You can however, grab a reference to the function by clever use of eval which you can later call in the setTimeout invocation. 但是,您可以通过巧妙地使用eval来获取对该函数的引用 ,您可以稍后在setTimeout调用中对其进行调用。

var F=eval(funcName);// gain a reference to the function given the function's name
cTimer = setTimeout(F, 1000);

If you're using AIR or don't trust the functionName string you can do the following: 如果您使用的是AIR或不信任functionName字符串,则可以执行以下操作:

function Test(){
 var functionContainer={
  t:function(){
   console.log("it's t");
  }
 };
 this.callT=function(functionName){
  var F=functionContainer[functionName];
  console.log("F is:",F);
  setTimeout(F,500);
 }
}
(new Test()).call("t");

This is preferable since you are invoking setTimeout with a function's name and not a string. 这是可取的,因为您要使用函数名称而不是字符串来调用setTimeout In general, using setTimeout with a string can have issues, it's hard to debug or maintain. 通常,将setTimeout与字符串一起使用可能会遇到问题,很难调试或维护。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 当我将其名称作为字符串时,如何执行私有JavaScript函数 - How to execute a private JavaScript function when I have its name as a string 当其名称作为字符串传递给函数时,如何执行JavaScript函数? - How to execute a JavaScript function when its name is passed as a string in function? 如何在Edge中执行名称为字符串的JavaScript函数 - How to execute a JavaScript function having its name as a string in Edge 当我将其名称作为字符串时执行 JavaScript 函数 - 不工作 - Execute a JavaScript function when I have its name as a string - Not working 当我将其名称作为字符串时如何执行 JavaScript function - How to execute a JavaScript function when I have its name as a string 如何按名称执行带参数的函数 - How to execute function with parameters by its name 在其类内调用函数 - Call function inside its Class 当我不带参数动态将其名称作为字符串发送时,如何执行javascript函数 - how to execute javascript function when i send its name as string dynamically with out parameters 如何执行 JavaScript Function 当我将其名称作为字符串时(使用具有重载参数的参数) - How to execute a JavaScript Function When I have its name as a string (with parameters that have an overload argument) JavaScript中是否可以使用字符串格式的名称来调用在另一个函数范围内声明的函数? - Is there any way in JavaScript to call a function declared inside the scope of another function by using its name available in string format?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM