diff options
author | Peter Bengtsson <mail@peterbe.com> | 2020-12-08 14:42:52 -0500 |
---|---|---|
committer | Peter Bengtsson <mail@peterbe.com> | 2020-12-08 14:42:52 -0500 |
commit | 074785cea106179cb3305637055ab0a009ca74f2 (patch) | |
tree | e6ae371cccd642aa2b67f39752a2cdf1fd4eb040 /files/ru/web/javascript/reference/global_objects/eval | |
parent | da78a9e329e272dedb2400b79a3bdeebff387d47 (diff) | |
download | translated-content-074785cea106179cb3305637055ab0a009ca74f2.tar.gz translated-content-074785cea106179cb3305637055ab0a009ca74f2.tar.bz2 translated-content-074785cea106179cb3305637055ab0a009ca74f2.zip |
initial commit
Diffstat (limited to 'files/ru/web/javascript/reference/global_objects/eval')
-rw-r--r-- | files/ru/web/javascript/reference/global_objects/eval/index.html | 213 |
1 files changed, 213 insertions, 0 deletions
diff --git a/files/ru/web/javascript/reference/global_objects/eval/index.html b/files/ru/web/javascript/reference/global_objects/eval/index.html new file mode 100644 index 0000000000..ee90713bde --- /dev/null +++ b/files/ru/web/javascript/reference/global_objects/eval/index.html @@ -0,0 +1,213 @@ +--- +title: eval() +slug: Web/JavaScript/Reference/Global_Objects/eval +tags: + - JavaScript + - NeedsUpdate + - Reference +translation_of: Web/JavaScript/Reference/Global_Objects/eval +--- +<div>{{jsSidebar("Objects")}}</div> + +<div class="blockIndicator warning"> +<p><strong>Warning:</strong> <font>Выполнение кода JavaScript с текстовой строки - это невероятный риск для безопасности. </font><font>Злоумышленнику слишком легко запустить какой угодно код, когда вы используете</font> <code>eval()</code>. Смотрите <a href="#Не_используйте_eval_без_необходимости!">Никогда не изпользуте eval()!</a>, ниже.</p> +</div> + +<p>Метод <code><strong>eval()</strong></code> выполняет JavaScript код, представленный строкой.</p> + +<p>{{EmbedInteractiveExample("pages/js/globalprops-eval.html")}}</p> + +<div class="hidden"> +<p>The source for this interactive example is stored in a GitHub repository. If you'd like to contribute to the interactive examples project, please clone <a href="https://github.com/mdn/interactive-examples">https://github.com/mdn/interactive-examples</a> and send us a pull request.</p> +</div> + +<h2 id="Синтаксис">Синтаксис</h2> + +<pre class="syntaxbox notranslate"><code>eval(<em>string</em>)</code></pre> + +<h3 id="Параметры">Параметры</h3> + +<dl> + <dt><code>string</code></dt> + <dd>Строка, представленная JavaScript выражением, оператором или последовательностью операторов. Выражение может содержать переменные и свойства существующих объектов.</dd> + <dt> + <h3 id="Возвращаемое_значение">Возвращаемое значение</h3> + </dt> + <dd>Возвращает значение выполнения кода, переданного в функцию в виде строки. Если код не возвращает ничего - будет возвращено значение {{jsxref("undefined")}}.</dd> +</dl> + +<h2 id="Описание">Описание</h2> + +<p><code>eval()</code> - функция глобального объекта.</p> + +<p>Аргумент функции <code>eval()</code> - строка. <code>eval()</code> исполняет содержащееся в строке выражение, один или несколько операторов JavaScript. Не стоит вызывать <code>eval()</code> для определения значения арифметического выражения; JavaScript вычисляет их автоматически.</p> + +<p><code>eval()</code> можно использовать для вычисления значения арифметического выражения, записанного в строковом виде, на более поздней стадии исполнения. Предположим, существует переменная <code>x</code>. Можно отложить вычисление выражения, в котором содержится <code>х</code>, если присвоить переменной это выражение в виде строки (допустим, "<code>3 * x + 2</code>"), а затем вызвать <code>eval()</code> в более поздней точке кода.</p> + +<p>Если аргумент, переданный <code>eval()</code>, не является строкой, <code>eval() </code>возвращает его неизменным. В следующем примере определен конструктор <code>String</code>, и <code>eval()</code> не вычисляет значение выражения, записанного в строковом виде, а возвращает объект типа <code>String</code>.</p> + +<pre class="brush:js notranslate">eval(new String("2 + 2")); // возвращает объект типа String, содержащий "2 + 2" +eval("2 + 2"); // возвращает 4 +</pre> + +<p>Это ограничение легко обойти при помощи <code>toString()</code>.</p> + +<pre class="brush:js notranslate">var expression = new String("2 + 2"); +eval(expression.toString()); +</pre> + +<p>Если вы используете <code>eval</code> косвенно, вызовом его через ссылку, а не просто <code>eval</code>, в<a href="http://www.ecma-international.org/ecma-262/5.1/#sec-10.4.2"> ECMAScript 5</a> это работает в глобальной области видимости, а не в локальной; это значит, что <code>eval</code> будет вызван в глобальной области видимости, а код будет выполнен с отсутвием доступа к локальным переменным в пределах области видимости, где он был вызван.</p> + +<pre class="brush:js notranslate">function test() { + var x = 2, y = 4; + console.log(eval("x + y")); // Прямой вызов, использует локальную области видимости, результат - 6 + var geval = eval; + console.log(geval("x + y")); // Непрямой вызов, использует глобальную область видимости, бросит ReferenceError, т.к. `x` - не определен +} +</pre> + +<h2 id="Не_используйте_eval_без_необходимости!"><a name="dont-use-it"><code><font face="Open Sans, Arial, sans-serif">Н</font>е используйте eval без необходимости!</code></a></h2> + +<p><code>eval()</code> - опасная функция, которая выполняет код, проходящий со всеми привилегиями вызывателя. Если вы запускаете <code>eval()</code> со строкой, на которую могут влиять злоумышленники, то вы можете запустить вредоносный код на устройство пользователя с правами вашей веб-страницы/расширения. Наиболее важно, код третьей стороны может видеть область видимости, в которой был вызван <code>eval()</code>, что может может привести к атакам, похожим на {{jsxref("Global_Objects/Function", "Function")}}.</p> + +<p><code>Также eval(),</code>как правило, медленнее альтернатив, так как вызывает интерпретатор JS, тогда как многие другие конструкции оптимизированы современными JS движками.</p> + +<p>Есть безопасные (и быстрые!) альтернативы <code>eval()</code> для общих случаев использования.</p> + +<h3 id="Доступ_к_свойствам">Доступ к свойствам</h3> + +<p>Вам не следует использовать <code>eval()</code>, чтобы конвертировать имена свойств в свойства. Рассматривая следующий пример, где свойство объекта используемое для доступа неизвестно до выполнения кода. Это можно сделать с eval:</p> + +<pre class="brush:js notranslate">var obj = { a: 20, b: 30 }; +var propname = getPropName(); // возвращает "a" или "b" + +eval( "var result = obj." + propname ); +</pre> + +<p>Однако, <code>eval()</code> здесь не нужен. По факту, использование здесь его удивляет. Вместо него используйте <a href="/en-US/docs/Web/JavaScript/Reference/Operators/Property_Accessors" title="JavaScript/Reference/Operators/Member_Operators">доступ к свойствам</a>, который быстрее и безопаснее:</p> + +<pre class="brush:js notranslate">var obj = { a: 20, b: 30 }; +var propname = getPropName(); // возвращает "a" или "b" +var result = obj[ propname ]; // obj[ "a" ] то же, что и obj.a +</pre> + +<h3 id="Используйте_функции_вместо_исполнения_фрагментов_кода">Используйте функции вместо исполнения фрагментов кода</h3> + +<p>У JavaScript <a class="external" href="http://en.wikipedia.org/wiki/First-class_function" title="http://en.wikipedia.org/wiki/First-class_function">функции первого класса</a>, что значит, что вы можете передавать функции как аргументы, хранить их в переменных или свойвах объектах и так далее. Многие DOM API созданы с учетом этого, так что вы можете (и вам следует) писать:</p> + +<pre class="brush: js notranslate">// вместо setTimeout(" ... ", 1000) : +setTimeout(function() { ... }, 1000); + +// вместо elt.setAttribute("onclick", "...") использовать: +elt.addEventListener("click", function() { ... } , false); </pre> + +<p><a href="/en-US/docs/Web/JavaScript/Closures" title="JavaScript/Guide/Closures">Замыкания</a> также полезны как способ создания функций с параметрами без конкатенации строк.</p> + +<h3 id="Разбор_JSON_конвертирование_строк_в_JavaScript_объекты">Разбор JSON (конвертирование строк в JavaScript объекты)</h3> + +<p>Если строка, переданная в <code>eval()</code>, содержит данные (к примеру, массив: <code>"[1, 2, 3]"</code>), а не код, вам следует рассмотреть <a href="/en-US/docs/Glossary/JSON" title="JSON">JSON</a>, позволяющий строке использовать подмножество JavaScript синтаксиса для представления данных. Смотрите также: <a href="/en-US/docs/Downloading_JSON_and_JavaScript_in_extensions" title="Downloading_JSON_and_JavaScript_in_extensions">Загрузка JSON и JavaScript в расширениях</a>.</p> + +<p>Заметьте, что синтаксис JSON ограничен в сравнении с JavaScript синтаксисом, многие валидные JavaScript литералы не распарсятся в JSON. К примеру, лишние запятые в конце выражений не разрешены в JSON, а имена свойств (ключи) в объектах должны быть в двойных кавычках. Будьте уверены использовать серилизацию JSON для создания строк, которые потом будут разбираться как JSON.</p> + +<h3 id="Передавайте_данные_вместо_кода">Передавайте данные вместо кода</h3> + +<p>К примеру, расширение, созданное изменять содержимое веб-страниц, должно иметь правила, определенные в <a href="/en-US/docs/XPath" title="XPath">XPath</a>, а не JS коде.</p> + +<h3 id="Выполняйте_код_с_ограниченными_правами">Выполняйте код с ограниченными правами</h3> + +<p>Если выполнять код всё-таки необходимо, желательно это делать с уменьшенными привелегиями. Этот совет подходит, главным образом, к расширениям и XUL приложениям, которые могут использовать <a href="/en-US/docs/Components.utils.evalInSandbox" title="Components.utils.evalInSandbox">Components.utils.evalInSandbox</a>.</p> + +<h2 id="Примеры">Примеры</h2> + +<h3 id="Использование_eval">Использование <code>eval</code></h3> + +<p>В следующем коде оба выражения содержат <code>eval()</code>, возвращающий 42. Первое определяется строкой "<code>x + y + 1</code>"; второе - строкой "<code>42</code>".</p> + +<pre class="brush:js notranslate">var x = 2; +var y = 39; +var z = "42"; +eval("x + y + 1"); // возвращает 42 +eval(z); // вернёт 42 +</pre> + +<h3 id="Использование_eval_для_исполнения_строки_содержащей_операторы_JavaScript">Использование <code>eval</code> для исполнения строки, содержащей операторы JavaScript</h3> + +<p>Следующий пример использует <code>eval()</code> для получения значения выражения <code>str</code>. Эта строка состоит из JavaScript выражений, печатающих в консоль, и, если x равен пяти, присвающих z значение 42, или 0 в противном случае. Когда второе выражение будет исполнено, <code>eval()</code> будет считать выражения выполненными, а также это установит значение выражению переменной z и вернет его.</p> + +<pre class="brush:js notranslate">var x = 5; +var str = "if (x == 5) {console.log('z is 42'); z = 42;} else z = 0; "; + +console.log("z is ", eval(str));</pre> + +<h3 id="Последнее_выражение_выполняется">Последнее выражение выполняется</h3> + +<p><code>eval()</code> вернет значение последнего выполняемого выражения</p> + +<pre class="brush:js notranslate">var str = "if ( a ) { 1+1; } else { 1+2; }"; +var a = true; +var b = eval(str); // вернёт 2 + +console.log("b is : " + b); + +a = false; +b = eval(str); // вернёт 3 + +console.log("b is : " + b);</pre> + +<h3 id="eval_как_строковое_определение_функции_включающее_и_как_префикс_и_суффикс"><code>eval</code> как строковое определение функции, включающее "(" и ")" как префикс и суффикс</h3> + +<pre class="brush:js notranslate">var fctStr1 = "function a() {}" +var fctStr2 = "(function a() {})" +var fct1 = eval(fctStr1) // вернёт undefined +var fct2 = eval(fctStr2) // вернёт функцию +</pre> + +<h2 id="Спецификации">Спецификации</h2> + +<table class="standard-table"> + <tbody> + <tr> + <th scope="col">Спецификация</th> + <th scope="col">Статус</th> + <th scope="col">Комментарий</th> + </tr> + <tr> + <td>ECMAScript 1st Edition.</td> + <td>Стандарт</td> + <td>Изначальное определение.</td> + </tr> + <tr> + <td>{{SpecName('ES5.1', '#sec-15.1.2.1', 'eval')}}</td> + <td>{{Spec2('ES5.1')}}</td> + <td></td> + </tr> + <tr> + <td>{{SpecName('ES6', '#sec-eval-x', 'eval')}}</td> + <td>{{Spec2('ES6')}}</td> + <td></td> + </tr> + </tbody> +</table> + +<h2 id="Поддержка_браузерами">Поддержка браузерами</h2> + +<div id="compat-mobile"> +<div class="hidden"> +<p>The compatibility table on this page is generated from structured data. If you'd like to contribute to the data, please check out <a href="https://github.com/mdn/browser-compat-data">https://github.com/mdn/browser-compat-data</a> and send us a pull request.</p> +</div> + +<p>{{Compat("javascript.builtins.eval")}}</p> +</div> + +<h3 id="Gecko-специфичные_замечания">Gecko-специфичные замечания</h3> + +<ul> + <li>Исторически <code>eval()</code> имел второй необязательный аргумент, указывающий на то, в контексте какого объекта будет выполняться выражение. Этот аргумент не был стандартизован и был удален из SpiderMonkey в Gecko 1.9.1 (Firefox 3.5). См. {{bug(442333)}}.</li> +</ul> + +<h2 id="Смотрите_также">Смотрите также</h2> + +<ul> + <li>{{jsxref("Global_Objects/uneval", "uneval()")}}</li> + <li><a href="/en-US/docs/Web/JavaScript/Reference/Operators/Property_Accessors">Доступ к свойствам</a></li> +</ul> |