Когда я реализовывал движок JScript, я выступал за то, чтобы печатать рубашки EVAL IS EVIL , но, к сожалению, мы так и не смогли обойти это.
Моя самая большая проблема с eval - не очевидная атака внедрения вредоносного кода, хотя это, безусловно, вызывает огромную обеспокоенность. Моя самая большая проблема в том, что люди склонны использовать его как действительно большой молот для решения действительно небольших проблем. Большинство реальных случаев использования eval в дикой природе, когда я был в команде JScript, можно было легко решить с помощью таблицы поиска; и так как каждый объект в JScript уже является справочной таблицей, это не так обременительно. Eval снова запускает компилятор и полностью уничтожает способность компилятора оптимизировать ваш код .
Еще несколько мыслей в этом ключе смотрите в моих статьях 2003 года на эту тему:
Общее зло:
http://blogs.msdn.com/b/ericlippert/archive/2003/11/01/53329.aspx
Инъекция атаки зла:
http://blogs.msdn.com/b/ericlippert/archive/2003/11/04/53335.aspx
eval
создании больших кусков кода так, как это нравится приложениям вроде JSPacker? JSPacker + gzip обычно приводит к меньшим размерам файлов, чем любое другое решение само по себе, но, как вы правильно заметили, это по сути запускает компилятор дважды для одного и того же куска кода, а также накладные расходы для замены строк.eval()
это не создает угроза безопасности на клиент (браузер) коде.Большинство дыр в безопасности представляют собой дыры того же типа, что и в SQL-инъекции, а именно объединяют вводимые пользователем данные в код JavaScript. Разница в том, что, хотя есть способы обеспечить, чтобы это не происходило с SQL, с помощью JavaScript мало что можно сделать.
В качестве тривиального и бесполезного примера приведем упрощенный калькулятор JavaScript:
Одним из правильных примеров использования являются некоторые из упаковщиков JavaScript, которые сжимают JavaScript, вытаскивая общие слова и заменяя их короткими заменами из 1-2 символов. Затем упаковщик выводит все это вместе с кодом замены строки на основе сгенерированного словаря, а затем проверяет результат.
источник
Есть некоторые вещи, которые невозможно сделать в JS без Eval подобных функций (
eval
,Function
, и , возможно , больше).Взять
apply
к примеру. Его легко использовать при использовании обычных вызовов функций:foo.apply(null, [a, b, c])
Но как бы вы сделали это для объектов, которые вы создаете с помощью нового синтаксиса?
new Foo.apply(null, [a, b, c])
не работает, и не делают аналогичные формы.Но вы можете обойти это ограничение с помощью
eval
илиFunction
(я используюFunction
в этом примере):Пример:
Foo.New.apply(null, [a, b, c])
;Конечно, вы можете вручную создавать функции, которые
Function.prototype.New
используют, но это не только многословно и неуклюже, но и (по определению) должно быть конечным.Function
позволяет коду работать с любым количеством аргументов.источник
eval()
? »Несколько прямым ответом с моей стороны была разработка ориентированной на разработчика области тестирования API. Мы дали текстовую область на странице и кнопку Run. Центральная точка страницы была для них, чтобы они могли испытать вещи в Javascript против нашего API-интерфейса для взаимодействия с iframe, что было не так легко сделать в локальной среде.
Все злонамеренное, что могло быть сделано в этом случае, могло также быть сделано разработчиком, открывшим свои инструменты F12.
источник
Я согласен, что его следует использовать очень редко, но я нашел мощный пример использования
eval
.В Firefox появилась новая экспериментальная функция asm.js, с которой я работал. Это позволяет скомпилировать ограниченное подмножество языка Javascript в нативный код. Да, это очень круто, но у него есть ограничения. Вы можете думать об ограниченном подмножестве Javascript как о C-подобном языке, встроенном в Javascript. Это на самом деле не предназначено для чтения или написания людьми.
Это ограниченное подмножество Javascript не позволяет мне вставлять сгенерированный во время выполнения код в скомпилированный код после его компиляции.
Я написал некоторый код, который позволяет пользователю написать в знакомой форме математическое выражение и преобразовать его на лету в код asm.js. Если только я не хотел, чтобы код обрабатывался на стороне сервера (чего я не делаю),
eval
это единственный инструмент, который позволяет мне обрабатывать полученный код браузером в режиме реального времени.источник
Как отмечают другие, самое важное при работе с ними
eval
- это сохранять их в безопасности. Для этого вы хотите провести тщательную проверку аргументов и сохранитьeval
простой код, поскольку, как правило, гораздо сложнее поддерживать и защищать сгенерированный код во время выполнения.Тем не менее, мне нравится использовать
eval
для двух видов вещей (хотя, возможно, могут быть и лучшие, менее злые альтернативы):eval
это способ «явного кеширования кода», его можно использовать для повышения производительности. Обратите внимание, что оптимизаторы постоянно улучшаются, но просто нет никакой гарантии относительно того, что они могут сделать для вас. Делая вещи явными в коде, вы действительно можете помочь оптимизатору принимать более разумные решения.Этот подход с предварительно скомпилированным объектом , например, демонстрирует явные преимущества в производительности при использовании
eval
для итерации свойства объекта. Он также показывает начало мощной системы типов, которая может обеспечить неявную проверку ограничений и многое другое, практически без затрат.Многие опытные разработчики Javascript, вероятно, отметят, что это кроличья нора, поскольку, если вы начнете писать Javascript таким образом, вы по сути измените способ использования языка. Это, однако, не обязательно может быть плохо для тех, кто любит Javascript, но при этом не хватает фундаментальных языковых функций, которые могут быть достигнуты только путем изменения способа использования самого языка.
источник
У меня есть ситуация, когда eval выглядит как путь, вычисляя строку и возвращая существующую переменную, имя которой совпадает со строкой.
У меня есть несколько таблиц: table1ResultsTable, table2ResultsTable, tableNResultsTable. У меня есть переменные с одинаковыми именами, которые являются объектами данных JQuery. Я использую их для настройки таблиц и вызова функций с данными jQuery.
Каждой таблице присвоен класс = "resultsTable". Теперь мне нужно получить переменную при нажатии на таблицу. Я делаю это:
Таким образом, я получаю идентификатор таблицы, в которой была нажата ячейка, которая имеет то же имя, что и соответствующая ей переменная объекта данных. Если у кого-то есть предложения по улучшению, я бы хотел об этом узнать.
источник
event.target.parentElement.parentElement.parentElement
это ужасно. Кроме того, я ожидаю, что вызов eval вызовет ошибку «ошибка ссылки: [идентификатор] не определена», если только вы не намеренно используете оцениваемые идентификаторы (которые являются ошибочными, неправильными и могут вызвать странные вещи, если вы закончите до создания дубликатов идентификаторов).document.getElementById(ID).MySpecialProperty = MYSPECIALPROPERTYVALUE
(не сказать, что это тоже здорово, но это лучше, чем eval). Как указывает Эрик Липперт, «каждый объект в JScript уже является таблицей поиска».