Почему использование JavaScript-функции eval - плохая идея?

534

Функция eval - это мощный и простой способ динамического генерирования кода, так каковы предостережения?

Брайан Сингх
источник
92
Не Eval () Саймон Виллисон - 24ways.org/2005/dont-be-eval
Brian Singh
5
Как описано в moduscreate.com/javascript-performance-tips-tricks - (новая функция (str)) () более производительна, чем eval (str). Просто мои 2 цента :)
Grgur
3
очевидно новая функция (a) на 67% медленнее, чем eval (a) на хроме
что такое сон
для меня новые функции (а) на 80% медленнее последнего Chrome на OSX
Джон Смит
3
Я добавил статическую функцию, просто чтобы сравнить производительность. jsperf.com/eval-vs-new-function/2
Nepoxx

Ответы:

386
  1. Неправильное использование eval открывает ваш код для инъекционных атак

  2. Отладка может быть более сложной (без номеров строк и т. Д.)

  3. eval'd код выполняется медленнее (нет возможности компилировать / кэшировать eval'd код)

Редактировать: Как @Jeff Walden указывает в комментариях, # 3 сегодня менее верен, чем это было в 2008 году. Однако, хотя может происходить некоторое кэширование скомпилированных скриптов, это будет ограничено только скриптами, которые eval-повторялись без модификации. Более вероятным сценарием является то, что вы оцениваете скрипты, которые каждый раз подвергались небольшим изменениям и поэтому не могли быть кэшированы. Давайте просто скажем, что НЕКОТОРЫЙ eval'd код выполняется медленнее.

Prestaul
источник
2
@JeffWalden, отличный комментарий. Я обновил свой пост, хотя понимаю, что прошел год с тех пор, как вы его опубликовали. Xnzo72, если бы вы несколько уточнили свой комментарий (как это сделал Джефф), я мог бы с вами согласиться. Джефф указал на ключ: «Однократное вычисление одной и той же строки может избежать затрат на анализ». На самом деле, вы просто не правы; № 3 справедливо для многих сценариев.
Prestaul
7
@Prestaul: Поскольку предполагаемый злоумышленник может просто использовать любой инструмент разработчика для изменения JavaScript в клиенте, почему вы говорите, что Eval () открывает ваш код для инъекционных атак? Уже не открыт? (Я говорю о клиентском JavaScript, конечно)
Эдуардо Мольтени
60
@EduardoMolteni, нам все равно (и не может помешать) пользователям запускать js в своих собственных браузерах. Атаки, которых мы пытаемся избежать, это когда сохраненные пользователем значения сохраняются, а затем помещаются в javascript и eval'd. Например, я мог бы установить мое имя пользователя на: badHackerGuy'); doMaliciousThings();и если вы берете мое имя пользователя, объединяете его в некоторый скрипт и оцениваете его в браузерах других людей, тогда я могу запустить любой javascript, который я хочу, на их машинах (например, заставить их добавить +1 к моим сообщениям, опубликовать свои данные на моем сервере и т. д.)
Prestaul
3
В целом, # 1 верно для многих, если не для большинства вызовов функций. Опытные программисты не должны выделять и избегать eval () только потому, что неопытные программисты злоупотребляют им. Однако опытные программисты часто имеют лучшую архитектуру в своем коде, и eval () будет редко требоваться или даже задумываться из-за этой лучшей архитектуры.
frodeborli
4
@TamilVendhan Конечно, вы можете поставить точки останова. Вы можете получить доступ к виртуальному файлу, созданному Chrome, для вашего уклоненного кода, добавив debugger;оператор в ваш исходный код. Это остановит выполнение вашей программы в этой строке. Затем после этого вы можете добавить точки отладки, как если бы это был просто другой файл JS.
Сид
346

Eval не всегда зло. Есть моменты, когда это совершенно уместно.

Однако eval в настоящее время и исторически массово используется людьми, которые не знают, что делают. К сожалению, это включает людей, пишущих учебники JavaScript, и в некоторых случаях это может иметь последствия для безопасности - или, чаще, простые ошибки. Таким образом, чем больше мы можем сделать, чтобы поставить вопросительный знак над eval, тем лучше. Каждый раз, когда вы используете eval, вам нужно проверять, что вы делаете, потому что, скорее всего, вы могли бы сделать это лучше, безопаснее и чище.

Чтобы дать слишком типичный пример, установить цвет элемента с идентификатором, хранящимся в переменной 'potato':

eval('document.' + potato + '.style.color = "red"');

Если бы авторы приведенного выше кода имели представление об основах работы объектов JavaScript, они бы поняли, что вместо литеральных точечных имен можно использовать квадратные скобки, устраняя необходимость в eval:

document[potato].style.color = 'red';

... который намного легче читать, а также менее глючит.

(Но тогда кто-то, кто / действительно / знал, что они делают, скажет:

document.getElementById(potato).style.color = 'red';

что более надежно, чем хитрая старая уловка доступа к элементам DOM прямо из объекта документа.)

bobince
источник
82
Хм, думаю, мне повезло, когда я впервые изучал JavaScript. Я всегда использовал «document.getElementById» для доступа к DOM; по иронии судьбы, я делал это только тогда, потому что не знал, как работают объекты в JavaScript ;-)
Майк Спросс
5
согласна. Иногда eval подходит, например, для ответов JSON от
веб-сервисов
40
@schoetbi: Разве вы не должны использовать JSON.parse()вместо eval()JSON?
nyuszika7h
4
@bobince code.google.com/p/json-sans-eval работает во всех браузерах, как и github.com/douglascrockford/JSON-js . Json2.js Дуга Крокфорда использует eval для внутреннего использования, но с проверками. Кроме того, он совместим с поддержкой встроенного браузера JSON.
Мартейн
8
@bobince Существует нечто, называемое функцией обнаружения объектов и полифиллами, для обработки отсутствующих библиотек JSON и других вещей (посмотрите на modernizr.com )
MauganRa
37

Я считаю, что это потому, что он может выполнять любую функцию JavaScript из строки. С его помощью людям проще внедрить в приложение мошеннический код.

kemiller2002
источник
5
Какая альтернатива тогда?
Модерн
5
На самом деле альтернативой является просто написать код, который не требует этого. Крокфорд подробно расскажет об этом, и если вам нужно его использовать, он в значительной степени говорит, что это недостаток дизайна программы и его необходимо переработать. По правде говоря, я тоже с ним согласен. JS для всех его недостатков действительно гибок, и позволяет много места, чтобы сделать его гибким.
kemiller2002
3
Неверно, большинство фреймворков имеют метод для анализа JSON, и если вы не используете фреймворк, вы можете использовать JSON.parse (). Большинство браузеров поддерживают его, и если вы действительно в затруднении, вы можете довольно легко написать анализатор для JSON.
kemiller2002
6
Я не покупаю этот аргумент, потому что уже легко внедрить мошеннический код в приложение Javascript. У нас есть браузерные консоли, расширения сценариев и т. Д. Каждый фрагмент кода, отправляемый клиенту, является необязательным для выполнения клиентом.
user2867288
6
Дело в том, что мне проще внедрить код в ваш браузер. Допустим, вы используете eval в строке запроса. Если я заставлю вас щелкнуть ссылку, которая ведет на этот сайт с присоединенной строкой запроса, я теперь выполнил свой код на вашем компьютере с полным разрешением браузера. Я хочу регистрировать все, что вы вводите на этом сайте, и отправлять мне? Готово, и нет никакого способа остановить меня, потому что когда eval выполняется, браузер дает ему высшие полномочия.
kemiller2002
27

На ум приходят два момента:

  1. Безопасность (но пока вы сами генерируете строку для оценки, это может быть проблемой)

  2. Производительность: до тех пор, пока исполняемый код неизвестен, его нельзя оптимизировать. (о javascript и производительности, конечно же, презентации Стива Йегге )

xtofl
источник
9
Почему безопасность является проблемой, если клиент все равно может делать с нашим кодом все, что он хочет? Грязная обезьяна ?
Павел Бревчински
2
@PaulBrewczynski, проблема безопасности возникает, когда пользователь A сохраняет свою часть кода для последующего использования, evalа затем этот маленький фрагмент кода запускается в браузере пользователя B
Felipe Pereira
21

Передача пользовательского ввода в eval () представляет собой угрозу безопасности, но каждый вызов eval () создает новый экземпляр интерпретатора JavaScript. Это может быть ресурсным боровом.

Эндрю Хеджес
источник
27
За три с лишним года, с тех пор как я ответил на это, мое понимание того, что происходит, скажем, углубилось. На самом деле происходит новый контекст выполнения. См. Dmitrysoshnikov.com/ecmascript/chapter-1-execution-contexts
Эндрю Хеджес
20

Как правило, это проблема, только если вы передаете пользовательский ввод eval.

Марк Бик
источник
16

В основном, это намного сложнее поддерживать и отлаживать. Это как goto. Вы можете использовать его, но это усложняет поиск проблем и усложняет работу с людьми, которым может потребоваться внести изменения позже.

Брайан
источник
Eval может использоваться для замены отсутствующих функций метапрограммирования, таких как шаблоны. Мне больше нравится компактный генератор, чем бесконечный список функций над функциями.
Слабое время
Пока строка не приходит от пользователя или ограничена браузером, вы можете. JavaScript обладает большой силой метапрограммирования, используя такие вещи, как изменение прототипов, obj [member], Proxy, json.parse, window, функции декоратора (adverbs), где newf = decorator (oldf), функция более высокого порядка, например Array.prototype.map (f). , передача аргументов другим функциям, аргументы ключевых слов через {}. Можете ли вы сказать мне случай использования, где вы не можете сделать это вместо Eval?
aoeu256
13

Следует иметь в виду, что вы часто можете использовать eval () для выполнения кода в иным образом ограниченной среде - сайты социальных сетей, которые блокируют определенные функции JavaScript, иногда можно обмануть, разбив их на блоки eval -

eval('al' + 'er' + 't(\'' + 'hi there!' + '\')');

Так что, если вы хотите запустить какой-то код JavaScript, который иначе не мог бы быть разрешен ( Myspace , я смотрю на вас ...), тогда eval () может быть полезным трюком.

Тем не менее, по всем причинам, указанным выше, вы не должны использовать его для своего собственного кода, где у вас есть полный контроль - это просто не нужно, и лучше отойти на полку «хитрых хаков JavaScript».

Мэтт Лохкамп
источник
1
Просто обновите приведенный выше код .. - Хи! - должен быть в кавычках, поскольку это строка. eval ('al' + 'er' + 't (' + '"привет!" + ")");
Махеш
2
[]["con"+"struc"+"tor"]["con"+"struc"+"tor"]('al' + 'er' + 't(\'' + 'hi there!' + '\')')()
Конрад Боровски,
4
Да, были сайты социальных сетей, которые ограничивали alert (), но позволяли eval () ?!
Joshden
12

Если вы не разрешите eval () динамический контент (через cgi или input), он будет таким же безопасным и надежным, как и любой другой JavaScript на вашей странице.

Thevs
источник
Хотя это правда - если ваш контент не динамический, то зачем вообще использовать eval для него? Вы можете просто поместить код в функцию и вызвать его, вместо этого!
Периата Breatta
Например, чтобы проанализировать возвращаемое значение (например, JSON, определенные сервером строки и т. Д.), Полученное при вызове Ajax.
Thevs
2
А ну понятно. Я бы назвал их динамическими, потому что клиент заранее не знает, что они собой представляют, но теперь я понимаю, что вы имеете в виду.
Периата Breatta
7

Наряду с остальными ответами, я не думаю, что у заявлений eval может быть продвинутая минимизация.

Пол Мендоса
источник
6

Это возможный риск для безопасности, он имеет другую область исполнения и совершенно неэффективен, поскольку создает совершенно новую среду сценариев для выполнения кода. Смотрите здесь для получения дополнительной информации: eval .

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

Том
источник
5

Если вы не уверены на 100%, что оцениваемый код получен из надежного источника (обычно из вашего собственного приложения), то это верный способ подвергнуть вашу систему атаке межсайтового скриптинга.

Джон Топли
источник
1
Только если ваша серверная безопасность - отстой. Безопасность на стороне клиента - нонсенс.
doubleOrt
5

Я знаю, что это обсуждение старое, но мне действительно нравится этот подход от Google, и я хотел поделиться этим чувством с другими;)

Другое дело, что чем лучше Ты получаешь, тем больше Ты пытаешься понять и, в конце концов, Ты просто не веришь, что что-то хорошо или плохо, только потому, что кто-то так сказал :) Это очень вдохновляющее видео, которое помогло мне больше думать самостоятельно :) ХОРОШИЕ ПРАКТИКИ хороши, но не используйте их безрассудно :)

op1ekun
источник
1
Да. Я нашел, по крайней мере, в Chrome, вариант использования, который кажется более эффективным. Запуск RAF, который выявляет строку в данной переменной на каждой итерации. Используйте setInterval для установки только графически ориентированных вещей, таких как установка преобразований и т. Д. В этой строке. Я пробовал много других подходов, таких как циклическое прохождение функций в массиве или использование переменной для установки преобразований только для измененных элементов, но пока это кажется наиболее эффективным. Когда дело доходит до анимации, самый верный стендовый тест - ваши глаза.
Jdmayfield
5

Это не обязательно так плохо, если вы знаете, в каком контексте вы его используете.

Если ваше приложение использует eval()для создания объекта из некоторого JSON, который вернулся из XMLHttpRequest на ваш собственный сайт, созданный вашим доверенным кодом на стороне сервера, это, вероятно, не проблема.

Ненадежный код JavaScript на стороне клиента в любом случае не может этого сделать. Если вещь, на которой вы выполняете eval(), поступила из разумного источника, у вас все хорошо.

MarkR
источник
3
Разве использование eval медленнее, чем просто анализ JSON?
Брендан Лонг
@Qix - запуск этого теста в моем браузере (Chrome 53) показывает, что eval несколько быстрее, чем анализ .
Периата Breatta
@PeriataBreatta Да, странно. Интересно, почему. В то время я сказал, что это не так. Тем не менее, Chrome не случайно получает странное повышение производительности в определенных областях среды исполнения от версии к версии.
Qix - МОНИКА БЫЛА ПОВРЕЖДЕНА
Небольшая старая ветка здесь, но из того, что я прочитал - не утверждая, что я сам ее проследил - JSON.parse на самом деле eval - это вклад в финальную стадию. Таким образом, с точки зрения эффективности, требуется больше работы / времени. Но с точки зрения безопасности, почему бы просто не разобрать? Eval это потрясающий инструмент. Используйте это для вещей, которые не имеют другого пути. Чтобы передать функции через JSON, есть способ сделать это без eval. Этот второй параметр в JSON.stringify позволяет вам запустить функцию обратного вызова, которую вы можете проверить с помощью typeof, если это функция. Затем получите функцию .toString (). Есть несколько хороших статей по этому вопросу, если вы ищете.
Jdmayfield
4

Это значительно снижает ваш уровень уверенности в безопасности.

Дэвид Племптон
источник
4

Если вы хотите, чтобы пользователь вводил некоторые логические функции и оценивал И ИЛИ, тогда JavaScript-функция eval идеально подходит. Я могу принять две строки и eval(uate) string1 === string2т. Д.

Ян
источник
Вы также можете использовать Function () {}, но будьте осторожны при их использовании на сервере, если только вы не хотите, чтобы пользователи захватили ваш сервер, хахахах.
aoeu256
3

Если вы заметили использование eval () в своем коде, помните мантру «eval () - зло».

Эта функция принимает произвольную строку и выполняет ее как код JavaScript. Когда рассматриваемый код известен заранее (не определяется во время выполнения), нет смысла использовать eval (). Если код генерируется динамически во время выполнения, часто есть лучший способ достичь цели без eval (). Например, просто использовать квадратную скобку для доступа к динамическим свойствам лучше и проще:

// antipattern
var property = "name";
alert(eval("obj." + property));

// preferred
var property = "name";
alert(obj[property]);

Использование eval()также имеет последствия для безопасности, потому что вы можете выполнять код (например, поступающий из сети), который был подделан. Это распространенный антипаттерн при работе с JSON-ответом на запрос Ajax. В этих случаях лучше использовать встроенные в браузер методы для анализа ответа JSON, чтобы убедиться в его безопасности и допустимости. Для браузеров, которые не поддерживают JSON.parse()изначально, вы можете использовать библиотеку из JSON.org.

Также важно помнить, что передача строк в setInterval(), setTimeout()и Function()конструктор, по большей части, похожа на использование, eval()и поэтому ее следует избегать.

За кулисами JavaScript все еще должен оценить и выполнить строку, которую вы передаете как программный код:

// antipatterns
setTimeout("myFunc()", 1000);
setTimeout("myFunc(1, 2, 3)", 1000);

// preferred
setTimeout(myFunc, 1000);
setTimeout(function () {
myFunc(1, 2, 3);
}, 1000);

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

Есть небольшое потенциальное преимущество, потому что код, оцененный в new Function (), будет работать в локальной области функций, поэтому любые переменные, определенные с помощью var в оцениваемом коде, не станут автоматически глобальными.

Другой способ предотвратить автоматические глобальные переменные - eval()превратить вызов в непосредственную функцию.

12345678
источник
Можете ли вы предложить, как я могу оценить функционально-локальное имя динамической переменной без eval? Функции Eval (и аналогичные) являются последними курортами в большинстве языков, которые их содержат, но иногда это необходимо. В случае получения имени динамической переменной, является ли какое-либо решение более безопасным? В любом случае, сам javascript не предназначен для реальной безопасности (очевидно, что защита на стороне сервера является основной защитой). Если вам интересно, вот мой пример использования eval, который я бы хотел изменить: stackoverflow.com/a/48294208
Обычный Джо
2

Помимо возможных проблем безопасности, если вы выполняете пользовательский код, в большинстве случаев есть лучший способ, который не требует повторного анализа кода при каждом его выполнении. Анонимные функции или свойства объекта могут заменить большинство применений eval и намного безопаснее и быстрее.

Мэтью Крамли
источник
2

Это может стать более серьезной проблемой, так как браузеры следующего поколения выпускают некоторые разновидности JavaScript-компилятора. Код, выполняемый через Eval, может не работать так же хорошо, как и остальная часть вашего JavaScript на этих новых браузерах. Кто-то должен сделать некоторое профилирование.

Брайан
источник
2

Это одна из хороших статей, рассказывающих об eval и о том, как он не является злом: http://www.nczonline.net/blog/2013/06/25/eval-isnt-evil-just-misunderstood/

Я не говорю, что вы должны убежать и начать использовать eval () везде. На самом деле хороших сценариев использования eval () совсем немного. Определенно существуют проблемы с ясностью кода, отладкой и, конечно же, производительностью, которые не следует упускать из виду. Но вы не должны бояться использовать его, когда у вас есть случай, когда eval () имеет смысл. Попробуйте сначала не использовать его, но не позволяйте никому пугать вас, думая, что ваш код более хрупок или менее безопасен при правильном использовании eval ().

Амр Элгархи
источник
2

eval () очень мощный и может использоваться для выполнения оператора JS или оценки выражения. Но вопрос не в том, как использовать eval (), а в том, как злоумышленник влияет на строку, которую вы запускаете с помощью eval (). В конце вы будете использовать вредоносный код. С силой приходит большая ответственность. Так что используйте это с умом, если вы используете это. Это не сильно связано с функцией eval (), но эта статья содержит довольно хорошую информацию: http://blogs.popart.com/2009/07/javascript-injection-attacks/ Если вы ищете основы eval () смотрите здесь: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/eval

фита
источник
2

Механизм JavaScript имеет ряд оптимизаций производительности, которые он выполняет на этапе компиляции. Некоторые из них сводятся к возможности по существу статически анализировать код в процессе его лексического анализа и заранее определять, где находятся все объявления переменных и функций, так что для разрешения идентификаторов во время выполнения требуется меньше усилий.

Но если Механизм находит в коде eval (..), он, по сути, должен предположить, что вся его осведомленность о местоположении идентификатора может быть недействительной, потому что он не может точно знать, в какой момент времени лексинг точно, какой код вы можете передать eval (..) изменить лексическую область или содержимое объекта, который вы можете передать, чтобы создать новую лексическую область, к которой следует обращаться.

Другими словами, в пессимистическом смысле большинство из тех оптимизаций, которые он сделал бы, бессмысленно, если присутствует eval (..), поэтому он просто не выполняет оптимизацию вообще.

Это все объясняет.

Ссылка :

https://github.com/getify/You-Dont-Know-JS/blob/master/scope%20&%20closures/ch2.md#eval

https://github.com/getify/You-Dont-Know-JS/blob/master/scope%20&%20closures/ch2.md#performance

hkasera
источник
Никакой движок javascript не может найти и оценить код с гарантией 100%. Поэтому он должен быть готов к этому в любое время.
Джек Гиффин
2

Это не всегда плохая идея. Взять, к примеру, генерацию кода. Недавно я написал библиотеку под названием Hyperbars, которая ликвидирует разрыв между виртуальным домом и рулем . Это делается путем анализа шаблона руля и преобразования его в гиперсценарий, который впоследствии используется virtual-dom. Гиперскрипт сначала генерируется в виде строки, а перед возвращением eval()превращается в исполняемый код. Я нашел eval()в этой конкретной ситуации полную противоположность зла.

В основном из

<div>
    {{#each names}}
        <span>{{this}}</span>
    {{/each}}
</div>

К этому

(function (state) {
    var Runtime = Hyperbars.Runtime;
    var context = state;
    return h('div', {}, [Runtime.each(context['names'], context, function (context, parent, options) {
        return [h('span', {}, [options['@index'], context])]
    })])
}.bind({}))

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

Вы можете увидеть , как генерация кода было достигнуто , если вам интересно здесь .

Wikened
источник
2

Я бы сказал, что это не имеет значения, если вы используете eval()в JavaScript, который запускается в браузерах. * (Предостережение)

Все современные браузеры имеют консоль разработчика, где вы в любом случае можете выполнить произвольный javascript, и любой полуумный разработчик может взглянуть на ваш JS-источник и поместить все нужные ему кусочки в консоль разработчика, чтобы сделать то, что он хочет.

* Пока ваши конечные точки сервера имеют правильную проверку и санацию предоставленных пользователем значений, не должно иметь значения, что анализируется и обрабатывается в вашем клиентском JavaScript.

Если вы спросите, подходит ли оно для использования eval()в PHP, ответ будет НЕТ , если только вы не внесете в белый список какие-либо значения, которые могут быть переданы в ваш оператор eval.

Адам Копли
источник
Кроме того, есть консоль разработчика, вы также можете ввести javascript: code в строку URL для создания собственной консоли разработчика на странице, если ее нет, как в случае старых браузеров IE и мобильных устройств.
Дмитрий
1

Я не буду пытаться опровергнуть все, что было сказано ранее, но я предложу использовать eval (), который (насколько я знаю) не может быть реализован каким-либо другим способом. Вероятно, есть другие способы кодирования этого и, возможно, способы его оптимизации, но это делается от руки и без наворотов для ясности, чтобы проиллюстрировать использование eval, у которого действительно нет других альтернатив. То есть: динамические (или точнее) программно созданные имена объектов (в отличие от значений).

//Place this in a common/global JS lib:
var NS = function(namespace){
    var namespaceParts = String(namespace).split(".");
    var namespaceToTest = "";
    for(var i = 0; i < namespaceParts.length; i++){
        if(i === 0){
            namespaceToTest = namespaceParts[i];
        }
        else{
            namespaceToTest = namespaceToTest + "." + namespaceParts[i];
        }

        if(eval('typeof ' + namespaceToTest) === "undefined"){
            eval(namespaceToTest + ' = {}');
        }
    }
    return eval(namespace);
}


//Then, use this in your class definition libs:
NS('Root.Namespace').Class = function(settings){
  //Class constructor code here
}
//some generic method:
Root.Namespace.Class.prototype.Method = function(args){
    //Code goes here
    //this.MyOtherMethod("foo"));  // => "foo"
    return true;
}


//Then, in your applications, use this to instantiate an instance of your class:
var anInstanceOfClass = new Root.Namespace.Class(settings);

РЕДАКТИРОВАТЬ: кстати, я бы не советовал (по всем причинам безопасности, указанным ранее), чтобы вы основали свои имена объектов на вводе пользователем. Я не могу представить себе вескую причину, по которой вы захотите это сделать. Тем не менее, я хотел бы указать, что это не будет хорошей идеей :)

Carnix
источник
3
это не может быть сделано с namespaceToTest[namespaceParts[i]], нет необходимости в Eval здесь, так что if(typeof namespaceToTest[namespaceParts[i]] === 'undefined') { namespaceToTest[namespaceParts[i]] = {};единственная разница дляelse namespaceToTest = namespaceToTest[namespaceParts[i]];
user2144406
1

Вывоз мусора

Сборщик мусора в браузерах не имеет представления, можно ли удалить код из eval'а из памяти, поэтому он просто сохраняет его до перезагрузки страницы. Неплохо, если ваши пользователи скоро появятся на вашей странице, но это может стать проблемой для веб-приложений.

Вот скрипт для демонстрации проблемы

https://jsfiddle.net/CynderRnAsh/qux1osnw/

document.getElementById("evalLeak").onclick = (e) => {
  for(let x = 0; x < 100; x++) {
    eval(x.toString());
  }
};

Что-то такое простое, как приведенный выше код, приводит к тому, что небольшой объем памяти сохраняется до тех пор, пока приложение не умрет. Это хуже, когда уклоненный скрипт является гигантской функцией и вызывается через интервал.

JD
источник