简体   繁体   English

从字符串名称动态创建JavaScript函数

[英]Create a JavaScript function dynamically from a string name

Given a string classname , I want to dynamically create a new JavaScript function named after that string that can be used to instantiate objects. 给定一个字符串classname ,我想动态创建一个以该字符串命名的新JavaScript函数,该函数可用于实例化对象。

I've tried using eval() but for some reason the declared function does not appear in the global (window) scope. 我尝试使用eval()但由于某种原因,声明的函数不会出现在全局(窗口)范围内。

eval( "function " + classname + "() {}" );
window[ classname ]; // => undefined

Is there a way I can dynamically create a new function named after a string? 有没有办法可以动态创建一个以字符串命名的新函数?

Or, alternatively, give me some way to reference the created function after creating it via eval . 或者,或者,通过eval创建它后,给我一些方法来引用创建的函数。 Interestingly it appears as a local variable when I debug it in Safari. 有趣的是,当我在Safari中调试它时,它看起来像一个局部变量。

Update: 更新:

Got it! 得到它了! Of course it's obvious, I just use eval again to create the instance: 当然很明显,我只是再次使用eval来创建实例:

var myInstance = eval( "new " + classname );
myInstance.constructor.name; // => classname (yay)

This should work in my case because I only need to create one instance of the class right after it's declared. 这应该适用于我的情况,因为我只需要在声明后立即创建一个类的实例。 For the general case though see Pointy's answer. 对于一般情况,虽然看到Pointy的答案。

Yes: 是:

window[classname] = function() { ... };

Now, in honesty, that's not exactly like what you were attempting, but it's pretty close. 现在,诚实地说,这与你的尝试不完全相同 ,但它非常接近。 When you instantiate a function via a function expression like that, and without a name, the function can't refer to itself except via the name in the outer scope (in this case, the global scope). 当您通过类似的function 表达式实例化函数而没有名称时,除了通过外部作用域中的名称(在本例中为全局作用域)之外,该函数不能引用自身。

If that's important, what you could do is this: create the function with some stock "internal" name, and then assign it to the global name: 如果这很重要,你可以做的是:用一些股票“内部”名称创建函数,然后将其分配给全局名称:

function secretName() { ... }

window[classname] = secretName;
function registerFunction(functionBody) {
         "use strict";
         var script = document.createElement("script");
         script.innerHTML = "function " + functionBody;
         document.body.appendChild(script);
}
registerFunction("fooBar(x, y) { return x + y; }");
fooBar(1, 2); // will give you 3

Although this is essentially the same as eval() but it will register the function in the domain of the current page. 虽然这与eval()基本相同,但它会在当前页面的域中注册该函数。 You can later remove this script element, or reuse it for other functions. 您可以稍后删除此脚本元素,或将其重用于其他功能。

Try this: 试试这个:

var classname = "myFunction";

window[ classname ] = function () {};

alert( window[ classname ] ); // => undefined

In case you don't want to create new functions based on some string, but based on another similar function: (this might not be a good example but hope you can get the idea) 如果您不想基于某些字符串创建新函数,但基于另一个类似的函数:(这可能不是一个很好的例子,但希望您能得到这个想法)

function createListOfFunctions(functionNameList) {
  resultFunctions = {};

  // Loop all names to create a list of functions with those names
  $.each(functionNameList, function(index, functionName) {
    resultFunctions[functionName] = _createFunction(functionName);
  });

  return resultFunctions;
}

function _createFunction(name) {
  return function(anotherNameToCompare) {
    // customize this funciton whatever you like
    return name == anotherNameToCompare;
  };
}


// USAGE:
functionNameList = ['stack', 'overflow'];
result = createListOfFunctions(functionNameList); // result = { stack: function(name) {...}, overflow: function(name) {...} }

result.stack('stack'); // true
result.stack('not stack'); // false
result.overflow('overflow'); // true

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

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM