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

时间:2012-10-18 21:45:40

标签: javascript class function

给定一个字符串classname,我想动态创建一个以该字符串命名的新JavaScript函数,该函数可用于实例化对象。

我尝试过使用eval()但由于某种原因,声明的函数没有出现在全局(窗口)范围内。

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

有没有办法可以动态创建一个以字符串命名的新函数?

或者,或者,通过eval创建函数后,给我一些参考创建函数的方法。有趣的是,当我在Safari中调试它时,它看起来像一个局部变量。

更新

知道了!当然很明显,我只是再次使用eval来创建实例:

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

这应该适用于我的情况,因为我只需要在声明后立即创建一个类的实例。对于一般情况,虽然看到Pointy的答案。

4 个答案:

答案 0 :(得分:11)

是:

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

现在,诚实地说,这并不像你正在尝试的那样完全,但它非常接近。当您通过function 表达式实例化一个函数,并且没有名称时,除了通过外部作用域中的名称之外,该函数不能引用自身(在本例中,全球范围)。

如果这很重要,你可以做的是:用一些股票“内部”名称创建函数,然后将其分配给全局名称:

function secretName() { ... }

window[classname] = secretName;

答案 1 :(得分:7)

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

虽然这与eval()基本相同,但它会在当前页面的域中注册该函数。您可以稍后删除此脚本元素,或将其重用于其他功能。

答案 2 :(得分:2)

试试这个:

var classname = "myFunction";

window[ classname ] = function () {};

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

答案 3 :(得分:1)

如果你不想基于某个字符串创建新函数,但是基于另一个类似的函数:(这可能不是一个很好的例子,但希望你能得到这个想法)

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