Почему eval () существует? - PullRequest
       24

Почему eval () существует?

31 голосов
/ 01 февраля 2012

Многие программисты говорят, что это плохая практика использования функции eval():

Когда eval () JavaScript не является злом?

Я хотел бы воспользоваться моментом, чтобы рассмотреть предпосылку вашего вопроса - этот eval () является "злом" ...

Опасен ли этот eval ()?

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

Почему не eval () JSON?

Существует несколько способов, которые могут поставить под угрозу вашу безопасность ...

Есть ли когда-нибудь веская причина использовать eval ()?

Да - когда нет другого способа выполнить данную задачу с помощьюразумный уровень ясности ... Это исключает 99% случаев, когда используется eval ...

Почему eval небезопасен в javascript?

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

Так почему он вообще существует?

Ответы [ 6 ]

9 голосов
/ 01 февраля 2012

Потому что иногда - это необходимость.Все те же причины за / против использования eval в JavaScript, вероятно, можно объяснить, например, использованием отражения в Java.

Однако я согласен со всем, что вы цитировали в своем вопросе.Многие причины для его использования опрометчивы, и лучше всего делать по-другому - но иногда все еще есть необходимость, или это просто «лучший выбор» по сравнению с другими доступными альтернативами.(Я бы сфокусировался на ответах на Есть ли когда-нибудь веская причина использовать eval ()? по дополнительным причинам.)

+ 1 на ваш вопрос для хорошего исследования.

8 голосов
/ 01 февраля 2012

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

Языки без функции eval() могут определенно предоставить (подмножество «всех») этой функциональности, попросив каждого программиста по существу написать свои собственные eval() - лексизировать входные данные, проанализировать входные данные, по мере необходимости создавать новые объекты, запускать на них методы или функции черезпростые сравнения строк или аналогичные.По сути, продублируйте весь интерпретатор, который уже существует, отлажен и быстр.

6 голосов
/ 15 декабря 2012

Eval на самом деле является мощной функцией, и есть некоторые вещи, которые невозможно обойтись без него.Например:

  1. Оценить код, полученный с удаленного сервера.(Скажем, вы хотите создать сайт, которым можно удаленно управлять, отправив на него код JavaScript?)
  2. Оцените пользовательский код.Без eval вы не можете программировать, например, онлайн-редактор / REPL.
  3. Динамически создавать функции произвольной длины (function.length только для чтения, поэтому единственный способ использовать eval).
  4. Загрузка скрипта и возвращение его значения.Если ваш скрипт является, например, функцией с самовозвратом, и вы хотите оценить ее и получить ее результат (например: my_result = get_script_result("foo.js")), единственный способ программирования функции get_script_result - использовать внутри нее eval.
  5. Повторное создание функции в другом замыкании.

И все, что вы хотели бы сделать, - это создавать код на лету.

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

age_of_erick = 34;
age_of_john = 21;
person = "erick";
eval("console.log('age_of_"+person+"')");

И код ниже:

age = {erick:34, john:21};
person = "erick";
console.log(age["erick"]);

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

6 голосов
/ 07 февраля 2012

По этой теме есть исследовательская публикация:

Eval, что делают мужчины - широкомасштабное исследование использования Eval в приложениях JavaScript
Зеркало на Wayback Machine

Для меня это наиболее полный ответ на этот вопрос на сегодняшний день.

Цитата из резюме:

Мы записали поведение 337 МБ строк, переданных в качестве аргументов для 550 358 вызовов функции eval, выполняемой на более чем 10 000 веб-сайтов.

Среди прочего, они идентифицировали 9 категорий повторяющихся eval:

  1. JSON - строка или вариант JSON.
  2. JSONP - дополненная строка JSON.
  3. Библиотека - одно или несколько определений функций.
  4. Чтение - доступ для чтения к свойству объекта.
  5. Назначить - присвоение локальной переменной или свойству объекта.
  6. Typeof - Тип тестового выражения.
  7. Try - Тривиальный блок try / catch.
  8. Call - Простой вызов функции / метода.
  9. Пусто - пустая или пустая строка.

Фрагмент из заключения (слишком длинный, чтобы его можно было цитировать):

[...] Хотя многие варианты использования eval были законными, многие из них были ненужными и могли быть заменены эквивалентным и более безопасным кодом.Мы начали эту работу с надеждой, что она покажет, что eval можно заменить другими функциями.К сожалению, наши данные не подтверждают этот вывод. [...]

Бумага, которую стоит прочитать.

2 голосов
/ 01 февраля 2012

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

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

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

0 голосов
/ 11 августа 2015

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

...