Динамическое создание функции 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