Динамическое создание функции JavaScript из имени строки
Дана строка classname
, Я хочу динамически создать новую функцию JavaScript с именем после этой строки, которая может использоваться для создания экземпляров объектов.
Я пробовал использовать eval()
но по какой-то причине объявленная функция не появляется в глобальной (оконной) области.
eval( "function " + classname + "() {}" );
window[ classname ]; // => undefined
есть ли способ динамически создать новую функцию с именем строки?
или, альтернативно, дайте мне какой-то способ ссылаться на созданную функцию после ее создания via eval
. Интересно, что он появляется как локальная переменная, когда я отлаживаю его в Safari.
обновление:
понял! Конечно, это очевидно, я просто использую eval
снова, чтобы создать экземпляр:
var myInstance = eval( "new " + classname );
myInstance.constructor.name; // => classname (yay)
это должно работать в моем случае, потому что мне нужно создать только один экземпляр класса сразу после его объявления. Для общего случая, хотя заостренный ответ.
4 ответов
Да:
window[classname] = function() { ... };
Теперь, честно говоря, это не ровно нравится то, что вы пытались, но это довольно близко. Когда вы создаете экземпляр функции через function
выражение как это, и без имени, функция не может ссылаться на себя, кроме как через имя во внешней области (в данном случае, глобальной области).
Если это важно, вы можете сделать следующее: создайте функцию с некоторым запасным "внутренним" именем, а затем назначьте ее к глобальному названию:
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
хотя это по существу то же самое, что eval()
но он зарегистрирует функцию в домене текущей страницы. Позже этот элемент сценария можно удалить или повторно использовать для других функций.
попробуйте это:
var classname = "myFunction";
window[ classname ] = function () {};
alert( window[ classname ] ); // => undefined
Если вы не хотите создавать новые функции на основе некоторой строки, но на основе другой подобной функции: (это может быть не хороший пример, но надеюсь, что вы можете получить идею)
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