给定一个字符串classname
,我想动态创建一个以该字符串命名的新JavaScript函数,该函数可用于实例化对象。
我尝试过使用eval()
但由于某种原因,声明的函数没有出现在全局(窗口)范围内。
eval( "function " + classname + "() {}" );
window[ classname ]; // => undefined
有没有办法可以动态创建一个以字符串命名的新函数?
或者,或者,通过eval
创建函数后,给我一些参考创建函数的方法。有趣的是,当我在Safari中调试它时,它看起来像一个局部变量。
更新
知道了!当然很明显,我只是再次使用eval
来创建实例:
var myInstance = eval( "new " + classname );
myInstance.constructor.name; // => classname (yay)
这应该适用于我的情况,因为我只需要在声明后立即创建一个类的实例。对于一般情况,虽然看到Pointy的答案。
答案 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