10

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

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

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

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

或者,或者,在通过eval. 有趣的是,当我在 Safari 中调试它时,它显示为一个局部变量。

更新:

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

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

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

4

4 回答 4

12

是的:

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

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

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

function secretName() { ... }

window[classname] = secretName;
于 2012-10-18T21:46:49.867 回答
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()但是它会在当前页面的域中注册函数。您可以稍后删除此脚本元素,或将其重新用于其他功能。

于 2012-10-18T23:22:28.390 回答
2

试试这个:

var classname = "myFunction";

window[ classname ] = function () {};

alert( window[ classname ] ); // => undefined
于 2012-10-18T21:48:12.010 回答
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
于 2015-11-06T04:04:10.863 回答