Eval javascript что это
Eval: выполнение строки кода
Встроенная функция eval позволяет выполнять строку кода.
Строка кода может быть большой, содержать переводы строк, объявления функций, переменные и т.п.
Результатом eval будет результат выполнения последней инструкции.
Код в eval выполняется в текущем лексическом окружении, поэтому ему доступны внешние переменные:
Значения внешних переменных можно изменять:
Без use strict у eval не будет отдельного лексического окружения, поэтому x и f будут видны из внешнего кода.
Использование «eval»
В современной разработке на JavaScript eval используется весьма редко. Есть даже известное выражение – «eval is evil» («eval – это зло»).
Пожалуйста, имейте в виду, что код в eval способен получать доступ к внешним переменным, и это может иметь побочные эффекты.
Использование внутри eval локальных переменных из внешнего кода считается плохим решением, так как это усложняет задачу по поддержке такого кода.
Существует два пути, как гарантированно избежать подобных проблем.
Если код внутри eval не использует внешние переменные, то вызывайте его так – window.eval(. ) :
В этом случае код выполняется в глобальной области видимости:
Если коду внутри eval нужны локальные переменные, поменяйте eval на new Function и передавайте необходимые данные как аргументы:
Конструкция new Function объясняется в главе Синтаксис «new Function». Она создаёт функцию из строки в глобальной области видимости. Так что локальные переменные для неё невидимы, но всегда можно передать их как аргументы. Получается очень аккуратный код, как в примере выше.
Итого
Вызов eval(code) выполняет строку кода и возвращает результат последней инструкции.
Задачи
Eval-калькулятор
Создайте калькулятор, который запрашивает ввод какого-нибудь арифметического выражения и возвращает результат его вычисления.
В этой задаче нет необходимости проверять полученное выражение на корректность, просто вычислить и вернуть результат.
Давайте будем использовать eval для вычисления арифметических выражений:
Eval javascript что это
Метод eval() выполняет JavaScript-код, представленный строкой.
Синтаксис
Параметры
Возвращаемое значение
Описание
Н е используйте eval без необходимости!
Также eval(), как правило, медленнее альтернатив, так как вызывает интерпретатор JS, тогда как многие другие конструкции оптимизированы современными JS движками.
Есть безопасные (и быстрые!) альтернативы eval() для общих случаев использования.
Доступ к свойствам
Однако, eval() здесь не нужен. По факту, использование здесь его удивляет. Вместо него используйте доступ к свойствам, который быстрее и безопаснее:
Используйте функции вместо исполнения фрагментов кода
У JavaScript функции первого класса, что значит, что вы можете передавать функции как аргументы, хранить их в переменных или свойствах объектов и так далее. Многие DOM API созданы с учётом этого, так что вы можете (и вам следует) писать:
Замыкания также полезны как способ создания функций с параметрами без конкатенации строк.
Разбор JSON (конвертирование строк в JavaScript объекты)
Заметьте, что синтаксис JSON ограничен в сравнении с JavaScript синтаксисом, многие валидные JavaScript литералы не распарсятся в JSON. К примеру, лишние запятые в конце выражений не разрешены в JSON, а имена свойств (ключи) в объектах должны быть в двойных кавычках. Будьте уверены использовать сериализацию JSON для создания строк, которые потом будут разбираться как JSON.
Передавайте данные вместо кода
К примеру, расширение, созданное изменять содержимое веб-страниц, должно иметь правила, определённые в XPath, а не JS коде.
Выполняйте код с ограниченными правами
Если выполнять код всё-таки необходимо, желательно это делать с уменьшенными привелегиями. Этот совет подходит, главным образом, к расширениям и XUL приложениям, которые могут использовать Components.utils.evalInSandbox.
Примеры
Использование eval
Использование eval для исполнения строки, содержащей операторы JavaScript
Последнее выражение выполняется
eval() вернёт значение последнего выполняемого выражения
eval как строковое определение функции, включающее «(» и «)» как префикс и суффикс
Спецификации
Поддержка браузерами
BCD tables only load in the browser
Gecko-специфичные замечания
Смотрите также
Found a problem with this page?
Mozilla
© 2005- 2021 Mozilla and individual contributors. Content is available under these licenses.
Запуск кода из строки: метод eval
Запуск кода из строки: метод eval
Здравствуйте! В этом уроке речь пойдет о таком может малоизвестном методе eval. Функция eval(code) позволяет выполнить любой код, переданный ей в виде строки. И в этом кроется ее опасность ведь если ей передать зловредный код в виде строки, то он будет выполнен.
Этот код будет выполнен в текущей области видимости.
Использование eval
В простейшем случае eval всего лишь выполняет код, вот пример:
Но он может не только выполнить код, но и также вернуть результат.
Вызов eval возвращает последнее вычисленное выражение, например:
При вызове eval имеет полный доступ к локальным переменным.
Это означает, что переменные могут быть изменены или дополнены:
В строгом режиме eval имеет свою область видимости
В строгом режиме функционал eval чуть-чуть меняется.
При use strict код внутри eval по-прежнему сможет читать и менять внешние переменные, однако переменные и функции, объявленные внутри eval, не попадут наружу.
Другими словами, в новом стандарте eval имеет свою область видимости, а к внешним переменным обращается через замыкание, аналогично тому, как работают обычные функции.
Неграмотное использование eval
Начнём с того, что eval применяется довольно очень редко. Действительно редко. Есть даже такое выражение как «eval is evil» (eval – зло).
Причина проста: когда-то JavaScript был гораздо более слабым языком, чем сейчас, и некоторые вещи без eval было попросту сделать невозможно. Но те времена давно канули в лету. И теперь найти тот случай, когда действительно надо выполнить код из строки – это надо сильно постараться.
Но если вы действительно знаете, что это именно тот случай и вам просто необходим eval – есть несколько нбансов, которые нужно иметь в виду.
Доступ к локальным переменным – худшее, что можно сделать при eval.
Дело в том, что локальные переменные могут быть очень легко переименованы:
Переменная phrase может быть переименована в hello, и если строка str обращается к ней – будет ошибка.
Современные средства сжатия JavaScript переименовывают локальные переменные автоматически. Это считается безопасным, так как локальная переменная видна лишь внутри функции и если в ней везде поменять phrase на p, то никто этого и не заметит.
До сжатия:
На самом деле всё ещё проще – в данном случае утилита сжатия автоматически уберёт переменную a и код станет таким:
Итак, если где-то в функции есть eval, то его взаимодействие с локальными переменными будет нарушено.
Некоторые инструменты сжатия предупреждают, когда видят eval или стараются вообще не сжимать такой код вместе с его внешними функциями, но всё это борьба с последствиями кривого кода.
Как правило, eval не нужен, именно поэтому и говорят: «eval is evil».
Запуск скрипта в глобальной области
Хорошо взаимодействовать с локальными переменными нельзя.
Но, допустим, мы загрузили с сервера или вручную написали скрипт, который нужно выполнить. Желательно в глобальной области, вне любых функций, чтобы он уж точно к локальным переменным отношения не имел.
Здесь eval может пригодиться. Имеются 2 трюка для выполнения кода в глобальной области:
Оба способа можно объединить в единой функции globalEval(code), выполняющей код без доступа к локальным переменным:
Внешние данные через new Function
Итак, у нас есть код, который всё же нужно выполнить динамически, через eval, но не просто скрипт – а ему нужно передать какие-то значения.
Как мы говорили ранее, считать их из локальных переменных нельзя: это подвержено ошибкам при переименовании переменных и сразу ломается при сжатии JavaScript. Да и вообще, неочевидно и кривовато.
К счастью, существует отличная альтернатива eval, которая позволяет корректно взаимодействовать с внешним кодом: new Function.
Вызов new Function(‘a,b’, ‘..тело..’) создает функцию с указанными аргументами a,b и телом. Как мы помним, доступа к текущему замыканию у такой функции не будет, но вы можете передать параметры и получить результат.
JSON и eval
В браузерах IE7- не было методов JSON.stringify и JSON.parse, поэтому работа с JSON происходила через eval.
Этот способ работы с JSON давно устарел, но его можно встретить кое-где в старом коде, так что для примера рассмотрим его.
Вызов eval(code) выполняет код и, если это выражение, то возвращает его значение, поэтому можно в качестве кода передать JSON.
Зачем здесь нужны скобки eval( ‘(‘ + str + ‘)’ ), почему не просто eval(str)?
Поэтому если передать в eval объект напрямую, то интерпретатор подумает, что это на самом деле блок кода, а там внутри какие-то двоеточия
Вот, для примера, eval без скобок, он выдаст ошибку:
А если eval получает выражение в скобках ( … ), то интерпретатор точно знает, что это не блок кода, а объект:
Осторожно, злой JSON!
Если мы получаем JSON из недоверенного источника, например с чужого сервера, то разбор через eval может быть и опасен.
Например, чужой сервер может быть взломан (за свой-то код мы отвечаем, а вот за чужой – нет), и вместо JSON вставлен злонамеренный JavaScript-код.
Поэтому рекомендуется, всё же, использовать JSON.parse.
При разборе через JSON.parse некорректный JSON просто приведёт к ошибке, а вот при разборе через eval этот код реально выполнится, и он может вывести что-то на странице, перенаправить посетителя куда-то и т.п да мало ли что еще можно придумать.
Итоги
Задания
Eval-калькулятор
Вам надо написать интерфейс, который принимает математическое выражение (prompt) и возвращает его результат.
Проверять выражение на корректность не требуется.
Если вы нашли ошибку, пожалуйста, выделите фрагмент текста и нажмите Ctrl+Enter.
Русские Блоги
Вкус оператора eval в JavaScript
1. Первый опыт eval
Это выглядит действительно потрясающе. Эта функция есть во многих динамических языках, таких как Python и Ruby. Но я редко вижу это в коде.
Передаваемая здесь строка должна быть семантически согласованной, иначе будет сообщено о синтаксической ошибке.
Использование этого метода всегда было спорным. Я вижу следующие два утверждения.
1. Соображения безопасности
eval Более опасный. Подумайте об этой ситуации, если мы случайно поставим eval Часть интерфейса открыта. Фактически, это равносильно предоставлению нашим пользователям права выполнять код. Пользователи намеренно или непреднамеренно позволяют нам eval Некоторое строковое содержимое, не соответствующее грамматическим правилам, может привести к тому, что наша система выдаст исключение.
2. Недостаточная оптимизация
Современный интерпретатор JS оптимизирует большую часть синтаксического анализа JS и вызывает те eval() Функция не сильно оптимизирована.
Иногда нам может потребоваться получить доступ к различным свойствам объекта через итерацию, но мы не знаем заранее, какие свойства объекта необходимы, поэтому нет возможности жестко закодировать свойства в коде.
Если мы не знаем заранее, что ключ, к которому мы хотим получить доступ, ‘x’ Мы могли бы написать код выше. Фактически, вместо этого вы можете использовать следующий код. Хотя обязательный стандарт относительно низкий, я думаю, что это выражение более четкое.
Лучше не использовать eval, если вам не нужно
Потому что вы все еще можете написать такой код. Вот что я получил из информации. Более представительный:
Кажется, этот код в порядке, но он сообщит об этой ошибке
Почему это? так как eval Контекст и вызов при выполнении фактической строки параметров eval Контекст функции такой же, что делает eval(«return;») Он понимается как отдельный оператор, а не как оператор, выполняемый в другой функции. (Это может быть немного сложно понять). а также return; В этом нет никакого смысла, если он не помещен в функцию. Так что прямо сообщайте о грамматических ошибках.
Все еще не понимаете?
Посмотрев на меня для примера, я немного изменил исходный сценарий
Давайте посмотрим на более интересный пример
Результат финального прогона
показывает f Функция должна функционировать внутри x Переменные сращиваются, и g Глобальные переменные y Сращенный. Итак, эти две функции вызывают eval Контекст другой.
2. строгий режим eval
Вот также небольшое упоминание о строгом режиме Javascript. Если вы включите строгий режим в скрипте (сейчас это делается во многих местах, это может помочь нам написать более строгий код Javascript).
В нормальном режиме eval Грамматика относительно свободна.
В строгом режиме есть два основных ограничения.
Или простой пример:
Мы должны иметь возможность думать о результатах, напечатанных здесь 12 с участием 1 ;
Давайте попробуем этот скрипт в строгом режиме. В принципе, нам нужно только добавить в начале скрипта ‘use strict’; Вы можете включить строгий режим.
В это время запуск сценария под узлом сообщит об ошибке.
Здесь мы используем eval Создать локальные переменные y Ошибка, но мы можем изменить существующие локальные переменные x 。
Ах, я устала, а последний пример очень простой, стараемся освещать в строгом режиме eval Значение.
Интерпретатор сообщает об ошибке напрямую
Eval: run a code string
The built-in eval function allows to execute a string of code.
A string of code may be long, contain line breaks, function declarations, variables and so on.
The result of eval is the result of the last statement.
The eval’ed code is executed in the current lexical environment, so it can see outer variables:
It can change outer variables as well:
In strict mode, eval has its own lexical environment. So functions and variables, declared inside eval, are not visible outside:
Using “eval”
In modern programming eval is used very sparingly. It’s often said that “eval is evil”.
Please note that its ability to access outer variables has side-effects.
Using outer local variables inside eval is also considered a bad programming practice, as it makes maintaining the code more difficult.
There are two ways how to be totally safe from such problems.
If eval’ed code doesn’t use outer variables, please call eval as window.eval(. ) :
This way the code is executed in the global scope:
If eval’ed code needs local variables, change eval to new Function and pass them as arguments:
The new Function construct is explained in the chapter The «new Function» syntax. It creates a function from a string, also in the global scope. So it can’t see local variables. But it’s so much clearer to pass them explicitly as arguments, like in the example above.
Summary
A call to eval(code) runs the string of code and returns the result of the last statement.
Tasks
Eval-calculator
Create a calculator that prompts for an arithmetic expression and returns its result.
There’s no need to check the expression for correctness in this task. Just evaluate and return the result.
Let’s use eval to calculate the maths expression: