Не используйте, eval
если вы абсолютно, положительно другого выбора.
Как уже упоминалось, использование чего-то подобного было бы лучшим способом сделать это:
window["functionName"](arguments);
Это, однако, не будет работать с функцией пространства имен:
window["My.Namespace.functionName"](arguments); // fail
Вот как вы это сделаете:
window["My"]["Namespace"]["functionName"](arguments); // succeeds
Чтобы сделать это проще и обеспечить некоторую гибкость, вот удобная функция:
function executeFunctionByName(functionName, context /*, args */) {
var args = Array.prototype.slice.call(arguments, 2);
var namespaces = functionName.split(".");
var func = namespaces.pop();
for(var i = 0; i < namespaces.length; i++) {
context = context[namespaces[i]];
}
return context[func].apply(context, args);
}
Вы бы назвали это так:
executeFunctionByName("My.Namespace.functionName", window, arguments);
Обратите внимание, вы можете передать в любом контексте, который вы хотите, так что это будет делать то же, что и выше:
executeFunctionByName("Namespace.functionName", My, arguments);
My.Namespace.functionName()
,this
будет ссылаться наMy.Namespace
объект. Но когда вы звонитеexecuteFunctionByName("My.Namespace.functionName", window)
, нет никакого способаthis
обратиться к тому же самому. Возможно, ему следует использовать последнее пространство имен в качестве области действия илиwindow
если нет пространств имен. Или вы можете позволить пользователю указать область действия в качестве аргумента.Просто подумал, что выложу слегка измененную версию очень полезной функции Джейсона Бантинга .
Во-первых, я упростил первый оператор, указав второй параметр для slice () . Оригинальная версия работала нормально во всех браузерах, кроме IE.
Во- вторых, я заменил это с контекста в обратном заявлении; в противном случае это всегда указывало на окно, когда выполнялась целевая функция.
источник
Ответ на этот другой вопрос покажет вам, как это сделать: эквивалент Javascript для локальных элементов Python ()?
В принципе, вы можете сказать,
или, как многие другие предложили, вы можете просто использовать eval:
хотя это крайне небезопасно, если вы не абсолютно уверены в том, что вы делаете.
источник
Не могли бы вы просто сделать это:
Вы также можете выполнить любой другой JavaScript, используя этот метод.
источник
eval("My.Namespace.functionName()");
?var codeToExecute = "return My.Namespace.functionName()";
Я думаю, что элегантный способ сделать это - определить ваши функции в хеш-объекте. Затем вы можете получить ссылку на эти функции из хэша, используя строку. например
Тогда вы можете позвонить:
Где customFunction будет строкой, соответствующей функции, определенной в вашем объекте.
источник
С ES6 вы можете получить доступ к методам класса по имени:
результат будет:
источник
Object.create()
. const myObj = {method1 () {console.log ('1')}, method2 () {console.log ('2')}} myObj ['method1'] (); // 1 myObj ['method2'] (); // 2Две вещи:
избегайте Eval, это очень опасно и медленно
во-вторых, не имеет значения, где существует ваша функция, «глобальность» не имеет значения.
x.y.foo()
может быть включен черезx.y['foo']()
илиx['y']['foo']()
или дажеwindow['x']['y']['foo']()
. Вы можете цепляться бесконечно, как это.источник
Все ответы предполагают, что к функциям можно получить доступ через глобальную область (окно). Однако ФП не сделал этого предположения.
Если функции живут в локальной области видимости (или закрытии) и на них не ссылается какой-либо другой локальный объект, неудача: вам нужно использовать
eval()
AFAIK, увидеть динамический вызов локальной функции в javascriptисточник
Вам просто нужно преобразовать вашу строку в указатель
window[<method name>]
. пример:и теперь вы можете использовать его как указатель.
источник
Вот мой вклад в отличные ответы Джейсона Бантинга / Алекса Назарова, где я включаю проверку ошибок, запрошенную Crashalot.
С учетом этой (надуманной) преамбулы:
тогда следующая функция:
позволит вам вызывать функцию javascript по имени, хранящемуся в строке, либо в пространстве имен, либо в глобальном масштабе, с аргументами или без них (включая объекты Array), обеспечивая обратную связь по любым возникшим ошибкам (возможно, перехватывая их).
Пример вывода показывает, как это работает:
источник
if( typeof context[ functionName ] !== 'function' )
потому что context - window - определен, является объектом и массивом, но window ['abcd'] не существует, поскольку было определено как проблема в принятом ответ:window["My.Namespace.functionName"](arguments); // fail
В зависимости от того, где вы находитесь, вы также можете использовать:
или в nodejs
источник
Если вы хотите вызвать функцию объекта вместо глобальной функции с помощью
window["functionName"]
. Вы можете сделать это как;Пример:
источник
БЫТЬ ОСТОРОЖЕН!!!
Следует избегать вызова функции по строке в JavaScript по двум причинам:
Причина 1: некоторые обфускаторы кода разрушают ваш код, поскольку они изменяют имена функций, делая строку недопустимой.
Причина 2: гораздо сложнее поддерживать код, использующий эту методологию, так как гораздо труднее найти использование методов, вызываемых строкой.
источник
Вот мой подход Es6, который позволяет вам вызывать вашу функцию по имени в виде строки или имени функции, а также позволяет передавать разное количество аргументов различным типам функций:
источник
Удивлен, чтобы не упомянуть о setTimeout.
Чтобы запустить функцию без аргументов:
Чтобы запустить функцию с аргументами:
Для запуска глубоко именованной функции:
источник
runMe
с несколькими аргументами.Итак, как и другие говорили, безусловно, лучший вариант:
И, как сказал Джейсон Бантинг , это не сработает, если имя вашей функции содержит объект:
Итак, вот моя версия функции, которая будет выполнять все функции по имени (включая объект или нет):
источник
Более ООП решение ...
источник
Еще одна деталь на постах Джейсона и Алекса. Я нашел полезным добавить значение по умолчанию в контекст. Просто поставьте
context = context == undefined? window:context;
в начале функции. Вы можете изменитьwindow
любой предпочитаемый контекст, и тогда вам не нужно будет передавать одну и ту же переменную каждый раз, когда вы вызываете ее в контексте по умолчанию.источник
Чтобы добавить к ответу Джейсона Бантинга, если вы используете nodejs или что-то еще (и это работает в dom js), вы можете использовать
this
вместоwindow
(и помните: eval is evil :источник
В моем коде очень похожая вещь. У меня есть сгенерированная сервером строка, которая содержит имя функции, которое мне нужно передать в качестве обратного вызова для сторонней библиотеки. Итак, у меня есть код, который берет строку и возвращает «указатель» на функцию, или ноль, если он не найден.
Мое решение было очень похоже на " очень полезную функцию Джейсона Бантинга » * , хотя оно не выполнялось автоматически, и контекст всегда был в окне. Но это можно легко изменить.
Надеюсь, это будет кому-то полезно.
источник
Там тоже очень полезный способ.
http://devlicio.us/blogs/sergio_pereira/archive/2009/02/09/javascript-5-ways-to-call-a-function.aspx
источник
Я не могу не упомянуть еще одну хитрость, которая помогает, если у вас есть неизвестное количество аргументов, которые также передаются как часть строки, содержащей имя функции. Например:
var annoyingstring = 'call_my_func(123, true, "blah")';
Если ваш Javascript работает на HTML-странице, все, что вам нужно, это невидимая ссылка; Вы можете передать строку в
onclick
атрибут и вызватьclick
метод.<a href="#" id="link_secret"><!-- invisible --></a>
Или создайте
<a>
элемент во время выполнения.источник
Самый простой способ получить к нему доступ, как элемент
такой же как
источник
Вы можете вызвать функцию JavaScript в
eval("functionname as string")
любом из них. Как показано ниже: (eval - это чистая функция JavaScript)Рабочий пример: https://jsfiddle.net/suatatan/24ms0fna/4/
источник
Это работает для меня:
Я надеюсь, что это работает.
источник
Я не думаю, что вам нужны сложные промежуточные функции или eval или зависеть от глобальных переменных, таких как окно:
Он также будет работать с импортированными функциями:
источник
Без использования
eval('function()')
вы можете создать новую функцию с помощьюnew Function(strName)
. Приведенный ниже код был протестирован с использованием FF, Chrome, IE.источник
источник
Смотреть основные:
Существуй другой тип функции - это класс и посмотри пример nils petersohn
источник
Спасибо за очень полезный ответ. Я использую функцию Джейсона Бантинга в своих проектах.
Я расширил его, чтобы использовать его с дополнительным тайм-аутом, потому что обычный способ установить тайм-аут не будет работать. Смотрите вопрос abhishekisnot
источник