Простейший вариант использования
Если вы просто хотите выполнить тело функции (например, с eval
или с помощью Worker
API), вы можете просто добавить некоторый код, чтобы обойти все ловушкиизвлечения тела функции (что, как уже упоминалось, вообще плохая идея):
'(' + myFunction + ')()';
Я использую этот трюк в этом Worker
-связанном JSFiddle .
Полная сериализация функций с помощью точного отслеживания стека
Я также написал более полную библиотеку, которая может:
- Сериализовать любую функцию в строку
- Уметь отправлять это строковое представление куда-либо еще, выполнять его с любыми пользовательскими аргументами и иметь возможность воспроизводить исходную трассировку стека
Проверьте мой CodeBuilder
код здесь .
Обратите внимание, что большая часть кода заботится о том, чтобы мы получили точную трассировку стека, где бы мы ни выполняли сериализованную функцию в более поздний момент времени.
Эта скрипка демонстрацияУпрощенная версия этой логики:
- Используйте
JSON.stringify
для правильной сериализации функции (что удобно, например, когда мы хотим сделать ее частью большего сериализационного «пакета данных»). - Затем мы оборачиваем его в одну
eval
, чтобы снять экранирование строки, "JSON-ish" (JSON не разрешает функции + код, поэтому мы должны использовать eval
), а затем в другойeval
чтобы вернуть желаемый объект. - Мы также используем
//# sourceMappingURL
(или старую версию //@ sourceMappingURL
), чтобы показать правильное имя функции в трассировке стека. - Вы будетеобнаружим, что Stacktrace выглядит нормально, но не дает правильной информации о строках и столбцах относительно файла, в котором мы определили сериализованные функции, поэтому мой
Codebuilder
использует stacktracejs для исправлениячто.
Я использую материал CodeBuilder
в моей (теперь немного устаревшей) библиотеке RPC, где вы можете найти некоторые примеры того, как это используется:
serializeInlineFunction
пример serializeFunction
пример buildFunctionCall
пример