Преобразование строки в вызов функции JavaScript

Пройдите тест, узнайте какой профессии подходите

Я предпочитаю
0%
Работать самостоятельно и не зависеть от других
Работать в команде и рассчитывать на помощь коллег
Организовывать и контролировать процесс работы

Быстрый ответ

Для преобразования строки в функцию воспользуйтесь скобочной нотацией объекта window. Этот подход позволяет вызывать функцию, имя которой представлено в форме строки. Приведённый ниже пример демонстрирует, как это работает на практике:

JS
Скопировать код
const имяФункции = "вычислить";
const аргументы = [10, 20];

const результат = window[имяФункции](...аргументы);

function вычислить(x, y) {
  return x + y;
}

console.log(результат); // Выводит 30

Используя данную методику, можно обходиться без eval() и избегать с ним связанных рисков, вызывая только разрешённые функции из глобальной области видимости.

Кинга Идем в IT: пошаговый план для смены профессии

Понятие различных областей видимости и структурированных вызовов

В зависимости от задачи, функции могут быть не в глобальной области видимости, и вам придётся управлять вызовами функций в более сложных структурах, когда функции размещаются в объектах.

Вызов вложенных функций с элегантностью

Когда функция находится внутри объекта, для её корректного вызова используйте точечную или скобочную нотацию:

JS
Скопировать код
const namespace = {
  utils: {
    calculate: function(x, y) {
      return x + y;
    }
  }
};

const nestedFunctionName = "utils.calculate";
const args = [10, 20];

const segments = nestedFunctionName.split('.');
const result = segments.reduce((obj, key) => obj[key], window)(...args);
console.log(result); // Выводит 30

Проведите проверку перед "стартом"

Перед тем как вызвать функцию, убедитесь, что под именем действительно находится функция:

JS
Скопировать код
const isFunction = fnName => typeof window[fnName] === 'function';

if(isFunction(имяФункции)) {
  window[имяФункции](...аргументы);
} else {
  console.error(`Ошибка: функции с именем ${имяФункции} нет в глобальном объекте.`);
}

Безопасная альтернатива

Когда названия функций подаются динамически, вместо eval() используйте Function Constructor. Но помните, что эта техника тоже не лишена рисков:

JS
Скопировать код
const sum = new Function('a', 'b', 'return a + b');
console.log(sum(2, 6)); // Выводит 8

Визуализация

Преобразование строки в вызов функции можно представить как преобразование обычного бумажного самолётика в настоящий реактивный истребитель:

Markdown
Скопировать код
Строка "calculateSum" 📝 ➡️ превращается в ☁️✈️ (активирующую функцию)

Вот что происходит за кулисами:

JS
Скопировать код
var fn = window["calculateSum"];

fn(5, 10); // Функция выполняется: 15

Этапы преобразования от строки до выполнения функции можно осуществить всего в два шага.

Особенности работы с параметрами и контекстом this

Когда требуется управлять параметрами и контекстом this, дело усложняется. Но и на то есть решение.

Использование apply и call для точного управления

Когда требуется специфика параметров или определённый контекст this, на помощь придут методы apply или call:

JS
Скопировать код
const args = [arg1, arg2, arg3];
const context = {}; // Ваш контекст здесь

fn.apply(context, args);

fn.call(context, ...args);

Адаптация к переменному числу параметров

Если точное количество параметров неизвестно заранее, оператор расширения (...) поможет передать их в функцию как отдельные аргументы:

JS
Скопировать код
fn(...args);

Каррирование и частичное применение для задержанной передачи аргументов

Если параметры приходят не одновременно, можно накапливать их поэтапно с помощью каррирования или частичного применения функций:

JS
Скопировать код
function currySum(a) {
  return function(b) {
    return a + b;
  };
}

const addFive = currySum(5);
addFive(10); // Получаем 15

Сохранение актуальности: Лучшие практики и безопасность

Важно помнить о рисках безопасности и поддержке кода при динамическом вызове функций. Некоторые лучшие практики:

Минимализм

Минимизируйте сложности. Лучше использовать ссылки на функции или модель событийного программирования.

Чистота ввода

Санитизируйте данные, особенно если они происходят от пользователей или внешних источников. Безопасный код значительно снижает риск уязвимости.

Ограниченный доступ

Не предоставляйте свободный доступ к важным функциям в коде. Ограничивайте использование динамического вызова до доверенных частей программы.

Словарь для упорядочения

Сопоставляйте функции с их именами в надежном словаре, чтобы предотвратить неожиданные вызовы и упростить управление кодом:

JS
Скопировать код
const handlers = {
  calculate: (x, y) => x + y,
  subtract: (x, y) => x – y
};

const handlerName = 'calculate';
if(handlers[handlerName]) {
  handlers[handlerName](...args);
}

Полезные материалы

  1. Функции в JavaScript (MDN) — Подробное изучение функций в JavaScript.
  2. Как превратить строку в вызов функции JavaScript? (Stack Overflow) — Обсуждение вопроса динамического вызова функций с использованием строки среди профессионалов.
  3. eval() (MDN) — Описание функции eval() в JavaScript.
  4. Вызов функции в JavaScript (W3Schools) — Различные методы вызова функций.
  5. Спецификация ECMAScript (ECMA-262 5.1 Edition) — Описание конструктора функций в JavaScript.
  6. Синтаксис "new Function" — Рассмотрение создания динамических функций.
  7. Function.prototype.apply() (MDN) — Применение apply для контроля за this и аргументами.