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/functions | |
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/functions')
11 files changed, 2391 insertions, 0 deletions
diff --git a/files/ru/web/javascript/reference/functions/arguments/callee/index.html b/files/ru/web/javascript/reference/functions/arguments/callee/index.html new file mode 100644 index 0000000000..eaf41af79d --- /dev/null +++ b/files/ru/web/javascript/reference/functions/arguments/callee/index.html @@ -0,0 +1,141 @@ +--- +title: arguments.callee +slug: Web/JavaScript/Reference/Functions/arguments/callee +translation_of: Web/JavaScript/Reference/Functions/arguments/callee +--- +<div>{{jsSidebar("Functions")}}</div> + +<p>Свойство <code><strong>callee</strong> псевдомассива <strong>arguments</strong></code> хранит ссылку на функцию-родитель.</p> + +<h2 id="Описание">Описание</h2> + +<div class="warning"><strong>Внимание:</strong> В ES5 <a href="/en-US/docs/JavaScript/Reference/Functions_and_function_scope/Strict_mode" title="/en-US/docs/JavaScript/Reference/Functions_and_function_scope/Strict_mode">strict mode</a> использование <code>arguments.callee</code> запрещено.</div> + +<h3 id="Зачем_вообще_использовать_arguments.callee">Зачем вообще использовать <code>arguments.callee</code>?</h3> + +<p>В ранних версиях javaScript отсутствовала такая фишка, как <a href="https://developer.mozilla.org/ru/docs/Web/JavaScript/Reference/Operators/function#%D0%98%D0%BC%D0%B5%D0%BD%D0%BE%D0%B2%D0%B0%D0%BD%D0%BD%D0%BE%D0%B5_%D1%84%D1%83%D0%BD%D0%BA%D1%86%D0%B8%D0%BE%D0%BD%D0%B0%D0%BB%D1%8C%D0%BD%D0%BE%D0%B5_%D0%B2%D1%8B%D1%80%D0%B0%D0%B6%D0%B5%D0%BD%D0%B8%D0%B5">Named Function Expression </a>и единственным спасением было свойство <strong>callee</strong>. К примеру:</p> + +<pre class="brush: js">var f = function test() { + alert(typeof test); //undefined + alert(typeof arguments.callee); //function +} +</pre> + +<p>В нынешние времена, когда мы уже можем работать с <em>NFE</em>, надобность в использовании свойства <strong>callee </strong>сама собой отпадает<strong>.</strong></p> + +<pre class="brush: js">var f = function test(){ + alert(typeof test); //function +}</pre> + +<p> </p> + +<p>Действительно незаменимым оно остается всего в одной ситуации. Когда мы создаем анонимную функцию напрямую через конструктор <em>Function.</em></p> + +<pre class="line-numbers language-javascript"><code class="language-javascript"><span class="keyword token">var b = new Function("", "alert(typeof arguments.callee)");</span></code></pre> + +<p> </p> + +<h2 id="Пример_использования">Пример использования</h2> + +<p> </p> + +<h3 id="Использование_arguments.callee_для_создания_рекурсии">Использование <code>arguments.callee</code> для создания рекурсии</h3> + +<pre class="line-numbers language-javascript"><code class="language-javascript"><span class="keyword token">var factorial = function</span><span class="punctuation token">(</span>n<span class="punctuation token">)</span> <span class="punctuation token">{</span> + <span class="keyword token">return</span> n<span class="operator token"> == </span><span class="number token">1</span> <span class="operator token">?</span> <span class="number token">1</span> <span class="punctuation token">:</span> n<span class="operator token"> * </span>arguments<span class="punctuation token">.</span><span class="function token">callee</span><span class="punctuation token">(</span>n<span class="number token">-1</span><span class="punctuation token">)</span><span class="punctuation token">;</span> +<span class="punctuation token">}; + +</span><span class="keyword token">factorial</span></code>(7); +</pre> + +<p> </p> + +<h2 id="Specifications">Specifications</h2> + +<table class="standard-table"> + <tbody> + <tr> + <th scope="col">Specification</th> + <th scope="col">Status</th> + <th scope="col">Comment</th> + </tr> + <tr> + <td>{{SpecName('ES1')}}</td> + <td>{{Spec2('ES1')}}</td> + <td>Initial definition. Implemented in JavaScript 1.2</td> + </tr> + <tr> + <td>{{SpecName('ES5.1', '#sec-10.6', 'Arguments Object')}}</td> + <td>{{Spec2('ES5.1')}}</td> + <td> </td> + </tr> + <tr> + <td>{{SpecName('ES6', '#sec-arguments-exotic-objects', 'Arguments Exotic Objects')}}</td> + <td>{{Spec2('ES6')}}</td> + <td> </td> + </tr> + <tr> + <td>{{SpecName('ESDraft', '#sec-arguments-exotic-objects', 'Arguments Exotic Objects')}}</td> + <td>{{Spec2('ESDraft')}}</td> + <td> </td> + </tr> + </tbody> +</table> + +<h2 id="Browser_compatibility">Browser compatibility</h2> + +<p>{{CompatibilityTable}}</p> + +<div id="compat-desktop"> +<table class="compat-table"> + <tbody> + <tr> + <th>Feature</th> + <th>Chrome</th> + <th>Firefox (Gecko)</th> + <th>Internet Explorer</th> + <th>Opera</th> + <th>Safari</th> + </tr> + <tr> + <td>Basic support</td> + <td>{{CompatVersionUnknown}}</td> + <td>{{CompatVersionUnknown}}</td> + <td>{{CompatVersionUnknown}}</td> + <td>{{CompatVersionUnknown}}</td> + <td>{{CompatVersionUnknown}}</td> + </tr> + </tbody> +</table> +</div> + +<div id="compat-mobile"> +<table class="compat-table"> + <tbody> + <tr> + <th>Feature</th> + <th>Android</th> + <th>Chrome for Android</th> + <th>Firefox Mobile (Gecko)</th> + <th>IE Mobile</th> + <th>Opera Mobile</th> + <th>Safari Mobile</th> + </tr> + <tr> + <td>Basic support</td> + <td>{{CompatVersionUnknown}}</td> + <td>{{CompatVersionUnknown}}</td> + <td>{{CompatVersionUnknown}}</td> + <td>{{CompatVersionUnknown}}</td> + <td>{{CompatVersionUnknown}}</td> + <td>{{CompatVersionUnknown}}</td> + </tr> + </tbody> +</table> +</div> + +<h2 id="See_also">See also</h2> + +<ul> + <li>{{jsxref("Function")}}</li> +</ul> diff --git a/files/ru/web/javascript/reference/functions/arguments/caller/index.html b/files/ru/web/javascript/reference/functions/arguments/caller/index.html new file mode 100644 index 0000000000..0b6fe5cc4b --- /dev/null +++ b/files/ru/web/javascript/reference/functions/arguments/caller/index.html @@ -0,0 +1,100 @@ +--- +title: arguments.caller +slug: Web/JavaScript/Reference/Functions/arguments/caller +tags: + - Functions + - JavaScript + - Obsolete + - Property + - arguments +translation_of: Archive/Web/JavaScript/arguments.caller +--- +<div>{{jsSidebar("Functions")}}</div> + +<p>Устаревшее свойство <strong><code>arguments.caller</code></strong> использовалось для того, чтобы определить источник вызова функции, выполняющейся в текущий момент времени. Данное свойство было удалено и больше не работает.</p> + +<h2 id="Описание">Описание</h2> + +<p>Данное свойство больше не доступно, но вы все так же можете использовать {{jsxref("Function.caller")}}.</p> + +<pre class="brush: js">function whoCalled() { + if (whoCalled.caller == null) + console.log('Меня вызвали из глобальной области видимости.'); + else + console.log(whoCalled.caller + ' вызвал меня!'); +}</pre> + +<h2 id="Примеры">Примеры</h2> + +<p>Код, приведенный ниже, больше не работает, но раньше он использовался для проверки значения <code>arguments.caller</code> функции.</p> + +<pre class="brush: js example-bad">function whoCalled() { + if (arguments.caller == null) + console.log('Меня вызвали из глобальной области видимости.'); + else + console.log(arguments.caller + ' вызвал меня!'); +} +</pre> + +<h2 id="Спецификации">Спецификации</h2> + +<p>Не является частью какого-либо стандарта. Реализовано в JavaScript 1.1 и удалено в {{bug(7224)}}, поскольку влекло за собой потенциальную уязвимость.</p> + +<h2 id="Совместимость_с_браузерами">Совместимость с браузерами</h2> + +<p>{{CompatibilityTable}}</p> + +<div id="compat-desktop"> +<table class="compat-table"> + <tbody> + <tr> + <th>Возможность</th> + <th>Chrome</th> + <th>Firefox (Gecko)</th> + <th>Internet Explorer</th> + <th>Opera</th> + <th>Safari</th> + </tr> + <tr> + <td>Базовая поддержка</td> + <td>{{CompatNo}}</td> + <td>{{CompatNo}}</td> + <td>{{CompatNo}}<br> + <a href="https://msdn.microsoft.com/en-US/library/gg622933(v=vs.85).aspx">удалено в IE 9</a></td> + <td>{{CompatNo}}</td> + <td>{{CompatNo}}</td> + </tr> + </tbody> +</table> +</div> + +<div id="compat-mobile"> +<table class="compat-table"> + <tbody> + <tr> + <th>Возможность</th> + <th>Android</th> + <th>Chrome for Android</th> + <th>Firefox Mobile (Gecko)</th> + <th>IE Mobile</th> + <th>Opera Mobile</th> + <th>Safari Mobile</th> + </tr> + <tr> + <td>Базовая поддержка</td> + <td>{{CompatNo}}</td> + <td>{{CompatNo}}</td> + <td>{{CompatNo}}</td> + <td>{{CompatNo}}</td> + <td>{{CompatNo}}</td> + <td>{{CompatNo}}</td> + </tr> + </tbody> +</table> +</div> + +<h2 id="Смотрите_также">Смотрите также</h2> + +<ul> + <li>{{jsxref("Function")}}</li> +</ul> diff --git a/files/ru/web/javascript/reference/functions/arguments/index.html b/files/ru/web/javascript/reference/functions/arguments/index.html new file mode 100644 index 0000000000..13ef8edd8d --- /dev/null +++ b/files/ru/web/javascript/reference/functions/arguments/index.html @@ -0,0 +1,241 @@ +--- +title: Объект arguments +slug: Web/JavaScript/Reference/Functions/arguments +tags: + - Functions + - JavaScript + - Reference + - arguments +translation_of: Web/JavaScript/Reference/Functions/arguments +--- +<div> +<div>{{jsSidebar("Functions")}}</div> +</div> + +<p>Объект <code><strong>arguments</strong></code> — это подобный массиву объект, который содержит аргументы, переданные в функцию.</p> + +<div class="blockIndicator note"> +<p><strong>Примечание:</strong> Если вы пишите ES6-совместимый код, то лучше использовать <a href="https://developer.mozilla.org/ru/docs/Web/JavaScript/Reference/Functions/Rest_parameters">rest параметры</a>.</p> +</div> + +<div class="blockIndicator note"> +<p><strong>Примечание:</strong> "Подобный массиву" означает, что <code>arguments</code> имеет свойство {{jsxref("Functions/arguments/length", "length")}}, а элементы индексируются начиная с нуля. Но при это он не может обращаться к встроенным методам {{JSxRef("Array")}}, таким как {{jsxref("Array.forEach", "forEach()")}} или {{jsxref("Array.map", "map()")}}. Подробнее об этом в <a href="/ru/docs/Web/JavaScript/Reference/Functions/arguments#Описание">§Описании</a>.</p> +</div> + +<p>{{EmbedInteractiveExample("pages/js/functions-arguments.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">arguments</pre> + +<h2 id="Описание">Описание</h2> + +<p>Объект <code>arguments</code> — это локальная переменная, доступная внутри любой (нестрелочной) функции. Объект <code>arguments</code> позволяет ссылаться на аргументы функции внутри неё. Он состоит из переданных в функцию аргументов, индексация начинается с 0. Например, если в функцию было передано 3 аргумента, обратиться к ним можно следующим образом:</p> + +<pre class="brush: js">arguments[0] +arguments[1] +arguments[2] +</pre> + +<p>Аргументам может быть присвоено значение:</p> + +<pre class="brush: js">arguments[1] = 'new value';</pre> + +<p>Объект <code>arguments</code> не является {{jsxref("Array")}}. Он похож на массив, но не обладает ни одним из его свойств, кроме <code><a href="/ru/docs/Web/JavaScript/Reference/Functions/arguments/length" title="JavaScript/Reference/Functions_and_function_scope/arguments/length">length</a></code>. Например, у него нет метода <code><a href="/ru/docs/Web/JavaScript/Reference/Global_Objects/Array/pop" title="JavaScript/Reference/Global_Objects/Array/pop">pop</a></code>. Однако он может быть преобразован в обычный массив:</p> + +<pre class="brush: js">var args = Array.prototype.slice.call(arguments); +<code>var args = [].slice.call(arguments); +</code> +<code>// ES2015 +const args = Array.from(arguments);</code> +<code>const args = [...arguments];</code> +</pre> + +<div class="warning"> +<p>Использование <code>slice</code> на объекте <code>arguments</code> не позволяет сделать оптимизации в некоторых JavaScript движках (например, V8 — <a href="https://github.com/petkaantonov/bluebird/wiki/Optimization-killers#3-managing-arguments">подробнее</a>). Если они важны, можно попробовать вместо этого создать новый массив с аналогичной длиной и заполнить его элементами объекта <code>arguments.</code> Альтернативный вариант — использовать конструктор <code>Array</code> как функцию:</p> + +<pre class="brush: js"><code class="language-js"><span class="keyword token">var</span> args <span class="operator token">=</span> <span class="punctuation token">(</span>arguments<span class="punctuation token">.</span>length <span class="operator token">===</span> <span class="number token">1</span> <span class="operator token">?</span> <span class="punctuation token">[</span>arguments<span class="punctuation token">[</span><span class="number token">0</span><span class="punctuation token">]</span><span class="punctuation token">]</span> <span class="punctuation token">:</span> Array<span class="punctuation token">.</span><span class="function token">apply</span><span class="punctuation token">(</span><span class="keyword token">null</span><span class="punctuation token">,</span> arguments<span class="punctuation token">)</span><span class="punctuation token">)</span><span class="punctuation token">;</span></code></pre> +</div> + +<p>Объект <code>arguments</code> можно использовать при вызове функции с большим количеством аргументов, чем было предусмотрено в её объявлении. Такой способ удобен для функций, в которые допустимо передавать переменное количество аргументов. Можно воспользоваться <code><a href="/ru/docs/Web/JavaScript/Reference/Functions/arguments/length" title="JavaScript/Reference/Functions_and_function_scope/arguments/length">arguments.length</a></code>, чтобы определить количество переданных в функцию аргументов, а затем обработать каждый из них с помощью объекта <code>arguments</code>. Чтобы определить количество параметров функции, описанных в её <a href="/en-US/docs/Glossary/Signature/Function">сигнатуре</a>, можно использовать свойство <code><a href="/ru/docs/Web/JavaScript/Reference/Global_Objects/Function/length" title="JavaScript/Reference/Global_Objects/Function/length">Function.length</a></code>.</p> + +<h3 id="Использование_typeof_с_объектом_arguments">Использование <code>typeof</code> с объектом <code>arguments</code></h3> + +<p>Применение оператора <code>typeof</code> к <code>arguments</code> вернёт 'object'.</p> + +<pre><code>console.log(typeof arguments); // 'object'</code></pre> + +<p>Определение типов аргументов может быть выполнено применением оператора <code>typeof</code> и индексацией.</p> + +<pre><code>// выведет тип первого аргумента +console.log(typeof arguments[0]);</code></pre> + +<h3 id="Использование_оператора_расширения_для_объекта_arguments">Использование оператора расширения для объекта <code>arguments</code></h3> + +<p>Как и с обычными массиво-подобными объектами, для преобразования объекта <code>arguments</code> в обычный массив можно использовать метод {{jsxref("Array.from()")}} или <a href="/ru/docs/Web/JavaScript/Reference/Operators/Spread_operator">оператор расширения:</a></p> + +<pre class="brush: js"><code class="language-js"><span class="keyword token">var</span> args <span class="operator token">=</span> Array<span class="punctuation token">.</span><span class="keyword token">from</span><span class="punctuation token">(</span>arguments<span class="punctuation token">)</span><span class="punctuation token">;</span> +<span class="keyword token">var</span> args <span class="operator token">=</span> <span class="punctuation token">[</span><span class="punctuation token">.</span><span class="punctuation token">.</span><span class="punctuation token">.</span>arguments<span class="punctuation token">]</span><span class="punctuation token">;</span></code></pre> + +<h2 id="Свойства">Свойства</h2> + +<dl> + <dt><code><a href="/ru/docs/Web/JavaScript/Reference/Functions/arguments/callee" title="JavaScript/Reference/Functions_and_function_scope/arguments/callee">arguments.callee</a></code></dt> + <dd>Ссылка на функцию, которая выполняется в текущий момент.</dd> + <dt><code><a href="/en-US/docs/Web/JavaScript/Reference/Functions/arguments/caller" title="JavaScript/Reference/Functions_and_function_scope/arguments/caller">arguments.caller</a></code> {{ Obsolete_inline() }}</dt> + <dd>Ссылка на функцию, которая вызвала функцию, выполняющуюся в текущий момент.</dd> + <dt><code><a href="/ru/docs/Web/JavaScript/Reference/Functions/arguments/length" title="JavaScript/Reference/Functions_and_function_scope/arguments/length">arguments.length</a></code></dt> + <dd>Количество переданных в функцию аргументов.</dd> + <dt><code><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/arguments/@@iterator">arguments[@@iterator]</a></code></dt> + <dd>Возвращает новый объект <code>Array Iterator</code>, содержащий значения для каждого индекса в массиве.</dd> +</dl> + +<h2 id="Примеры">Примеры</h2> + +<h3 id="Создание_функции_соединяющей_несколько_строк">Создание функции, соединяющей несколько строк</h3> + +<p>Данный пример описывает функцию, которая соединяет несколько строк. Для этой функции объявлен только один аргумент, определяющий символ-разделитель соединяемых элементов. Функция определена следующим образом:</p> + +<pre class="brush:js line-numbers language-js"><code class="language-js"><span class="keyword token">function</span> <span class="function token">myConcat</span><span class="punctuation token">(</span>separator<span class="punctuation token">)</span> <span class="punctuation token">{</span> + <span class="keyword token">var</span> args <span class="operator token">=</span> Array<span class="punctuation token">.</span>prototype<span class="punctuation token">.</span>slice<span class="punctuation token">.</span><span class="function token">call</span><span class="punctuation token">(</span>arguments<span class="punctuation token">,</span> <span class="number token">1</span><span class="punctuation token">)</span><span class="punctuation token">;</span> + <span class="keyword token">return</span> args<span class="punctuation token">.</span><span class="function token">join</span><span class="punctuation token">(</span>separator<span class="punctuation token">)</span><span class="punctuation token">;</span> +<span class="punctuation token">}</span></code></pre> + +<p>Вы можете передать любое количество аргументов в эту функцию. Она создает строку, используя каждый аргумент:</p> + +<pre class="brush:js">// возвращает "red, orange, blue" +myConcat(", ", "red", "orange", "blue"); + +// получает "elephant; giraffe; lion; cheetah" +myConcat("; ", "elephant", "giraffe", "lion", "cheetah"); + +// выводит "sage. basil. oregano. pepper. parsley" +myConcat(". ", "sage", "basil", "oregano", "pepper", "parsley");</pre> + +<h3 id="Функция_создающая_HTML_списки"> Функция, создающая HTML списки</h3> + +<p>В данном примере приведена функция, которая создает строку с HTML-разметкой для списка. Единственный ее аргумент - строка, определяющая вид списка: если его значение равно "u", формируется неупорядоченный (маркированный) список, а если "o", то упорядоченный (нумерованный):</p> + +<pre class="brush:js">function list(type) { + var result = "<" + type + "l><li>"; + var args = Array.prototype.slice.call(arguments, 1); + result += args.join("</li><li>"); + result += "</li></" + type + "l>"; // конец списка + + return result; +}</pre> + +<p>Вы можете использовать любое количество аргументов, а функция добавит каждый элемент в список заданного первым аргументом типа. Например:</p> + +<pre class="brush:js">var listHTML = list("u", "One", "Two", "Three"); + +/* listHTML: + +"<ul><li>One</li><li>Two</li><li>Three</li></ul>" + +*/</pre> + +<h3 id="Оставшиеся_деструктурированные_и_параметры_по_умолчанию">Оставшиеся, деструктурированные и параметры по умолчанию</h3> + +<p>Объект <code>arguments</code> может использоваться совместно с <a href="/ru/docs/Web/JavaScript/Reference/Functions/Rest_parameters">оставшимися параметрами</a>, <a href="/ru/docs/Web/JavaScript/Reference/Functions/Default_parameters">параметрами по умолчанию </a>или <a href="/ru/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment">деструктурированными параметрами</a>.</p> + +<pre class="brush: js line-numbers language-js"><code class="language-js"><span class="keyword token">function</span> <span class="function token">foo</span><span class="punctuation token">(</span><span class="punctuation token">.</span><span class="punctuation token">.</span><span class="punctuation token">.</span>args<span class="punctuation token">)</span> <span class="punctuation token">{</span> + <span class="keyword token">return</span> arguments<span class="punctuation token">;</span> +<span class="punctuation token">}</span> +<span class="function token">foo</span><span class="punctuation token">(</span><span class="number token">1</span><span class="punctuation token">,</span> <span class="number token">2</span><span class="punctuation token">,</span> <span class="number token">3</span><span class="punctuation token">)</span><span class="punctuation token">;</span> <span class="comment token">// { "0": 1, "1": 2, "2": 3 }</span></code></pre> + +<p>Тем не менее, в нестрогих функциях <strong>соответствие между их аргументами и объектом <code>arguments</code></strong> существует только в том случае, если функция <strong>не</strong> содержит никаких <a href="/ru/docs/Web/JavaScript/Reference/Functions/Rest_parameters">оставшихся параметров</a>, <a href="/ru/docs/Web/JavaScript/Reference/Functions/Default_parameters">параметров по умолчанию</a> или <a href="/ru/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment">деструктурированных параметров</a>. Например, в функции, приведенной ниже, используется параметр по умолчанию, и в данном случае возвращаемый результат будет равен 10, а не 100:</p> + +<pre class="brush: js line-numbers language-js"><code class="language-js"><span class="keyword token">function</span> <span class="function token">bar</span><span class="punctuation token">(</span>a<span class="operator token">=</span><span class="number token">1</span><span class="punctuation token">)</span> <span class="punctuation token">{</span> + arguments<span class="punctuation token">[</span><span class="number token">0</span><span class="punctuation token">]</span> <span class="operator token">=</span> <span class="number token">100</span><span class="punctuation token">;</span> + <span class="keyword token">return</span> a<span class="punctuation token">;</span> +<span class="punctuation token">}</span> +<span class="function token">bar</span><span class="punctuation token">(</span><span class="number token">10</span><span class="punctuation token">)</span><span class="punctuation token">;</span> <span class="comment token">// 10</span></code></pre> + +<p>В следующем примере возвращается 100, поскольку здесь нет <a href="/ru/docs/Web/JavaScript/Reference/Functions/Rest_parameters">оставшихся параметров</a>, <a href="/ru/docs/Web/JavaScript/Reference/Functions/Default_parameters">параметров по умолчанию</a> или <a href="/ru/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment">деструктурированных параметров</a>:</p> + +<pre class="brush: js line-numbers language-js"><code class="language-js"><span class="keyword token">function</span> <span class="function token">zoo</span><span class="punctuation token">(</span>a<span class="punctuation token">)</span> <span class="punctuation token">{</span> + arguments<span class="punctuation token">[</span><span class="number token">0</span><span class="punctuation token">]</span> <span class="operator token">=</span> <span class="number token">100</span><span class="punctuation token">;</span> + <span class="keyword token">return</span> a<span class="punctuation token">;</span> +<span class="punctuation token">}</span> +<span class="function token">zoo</span><span class="punctuation token">(</span><span class="number token">10</span><span class="punctuation token">)</span><span class="punctuation token">;</span> <span class="comment token">// 100</span></code></pre> + +<p>На самом деле, если <a href="/ru/docs/Web/JavaScript/Reference/Functions/Rest_parameters">оставшиеся параметры</a>, <a href="/ru/docs/Web/JavaScript/Reference/Functions/Default_parameters">параметры по умолчанию</a> или <a href="/ru/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment">деструктурированные параметры</a> не используются, формальные аргументы будут ссылаться на последние значения объекта <strong><code>arguments</code></strong>, при считывании значений формальных аргументов будут считаны последние данные из <strong><code>arguments</code></strong>, а при изменении значений формальных аргументов будет обновлен и объект <strong><code>arguments</code></strong>. Пример приведен в коде ниже:</p> + +<pre class="brush: js line-numbers language-js"><code class="language-js"><span class="keyword token">function</span> <span class="function token">func</span><span class="punctuation token">(</span>a<span class="punctuation token">,</span> b<span class="punctuation token">)</span> <span class="punctuation token">{</span> + arguments<span class="punctuation token">[</span><span class="number token">0</span><span class="punctuation token">]</span> <span class="operator token">=</span> <span class="number token">90</span><span class="punctuation token">;</span> + arguments<span class="punctuation token">[</span><span class="number token">1</span><span class="punctuation token">]</span> <span class="operator token">=</span> <span class="number token">99</span><span class="punctuation token">;</span> + console<span class="punctuation token">.</span><span class="function token">log</span><span class="punctuation token">(</span>a <span class="operator token">+</span> <span class="string token">" "</span> <span class="operator token">+</span> b<span class="punctuation token">)</span><span class="punctuation token">;</span> +<span class="punctuation token">}</span> + +<span class="function token">func</span><span class="punctuation token">(</span><span class="number token">1</span><span class="punctuation token">,</span> <span class="number token">2</span><span class="punctuation token">)</span><span class="punctuation token">;</span> <span class="comment token">//90, 99</span></code></pre> + +<p>или</p> + +<pre class="brush: js line-numbers language-js"><code class="language-js"><span class="keyword token">function</span> <span class="function token">func</span><span class="punctuation token">(</span>a<span class="punctuation token">,</span> b<span class="punctuation token">)</span> <span class="punctuation token">{</span> + a <span class="operator token">=</span> <span class="number token">9</span><span class="punctuation token">;</span> + b <span class="operator token">=</span> <span class="number token">99</span><span class="punctuation token">;</span> + console<span class="punctuation token">.</span><span class="function token">log</span><span class="punctuation token">(</span>arguments<span class="punctuation token">[</span><span class="number token">0</span><span class="punctuation token">]</span> <span class="operator token">+</span> <span class="string token">" "</span> <span class="operator token">+</span> arguments<span class="punctuation token">[</span><span class="number token">1</span><span class="punctuation token">]</span><span class="punctuation token">)</span><span class="punctuation token">;</span> +<span class="punctuation token">}</span> + +<span class="function token">func</span><span class="punctuation token">(</span><span class="number token">3</span><span class="punctuation token">,</span> <span class="number token">4</span><span class="punctuation token">)</span><span class="punctuation token">;</span> <span class="comment token">//9, 99</span></code></pre> + +<p>Но в случае, когда применяются <a href="/ru/docs/Web/JavaScript/Reference/Functions/Rest_parameters">оставшиеся параметры</a>, <a href="/ru/docs/Web/JavaScript/Reference/Functions/Default_parameters">параметры по умолчанию</a> или <a href="/ru/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment">деструктурированные параметры</a>, будет обработано нормальное поведение, как в случае <a href="/ru/docs/Web/JavaScript/Reference/Functions/Default_parameters">параметров по умолчанию</a>:</p> + +<pre class="brush: js line-numbers language-js"><code class="language-js"><span class="keyword token">function</span> <span class="function token">func</span><span class="punctuation token">(</span>a<span class="punctuation token">,</span> b<span class="punctuation token">,</span> c<span class="operator token">=</span><span class="number token">9</span><span class="punctuation token">)</span> <span class="punctuation token">{</span> + arguments<span class="punctuation token">[</span><span class="number token">0</span><span class="punctuation token">]</span> <span class="operator token">=</span> <span class="number token">99</span><span class="punctuation token">;</span> + arguments<span class="punctuation token">[</span><span class="number token">1</span><span class="punctuation token">]</span> <span class="operator token">=</span> <span class="number token">98</span><span class="punctuation token">;</span> + console<span class="punctuation token">.</span><span class="function token">log</span><span class="punctuation token">(</span>a <span class="operator token">+</span> <span class="string token">" "</span> <span class="operator token">+</span> b<span class="punctuation token">)</span><span class="punctuation token">;</span> +<span class="punctuation token">}</span> + +<span class="function token">func</span><span class="punctuation token">(</span><span class="number token">3</span><span class="punctuation token">,</span> <span class="number token">4</span><span class="punctuation token">)</span><span class="punctuation token">;</span> <span class="comment token">//3, 4</span></code></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>{{SpecName('ES1')}}</td> + <td>{{Spec2('ES1')}}</td> + <td>Изначальное определение. Реализовано в JavaScript 1.1</td> + </tr> + <tr> + <td>{{SpecName('ES5.1', '#sec-10.6', 'Arguments Object')}}</td> + <td>{{Spec2('ES5.1')}}</td> + <td></td> + </tr> + <tr> + <td>{{SpecName('ES6', '#sec-arguments-exotic-objects', 'Arguments Exotic Objects')}}</td> + <td>{{Spec2('ES6')}}</td> + <td></td> + </tr> + <tr> + <td>{{SpecName('ESDraft', '#sec-arguments-exotic-objects', 'Arguments Exotic Objects')}}</td> + <td>{{Spec2('ESDraft')}}</td> + <td></td> + </tr> + </tbody> +</table> + +<h2 id="Поддержка_браузерами">Поддержка браузерами</h2> + +<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.functions.arguments")}}</p> + +<h2 id="Смотрите_также">Смотрите также</h2> + +<ul> + <li>{{jsxref("Function")}}</li> +</ul> diff --git a/files/ru/web/javascript/reference/functions/arguments/length/index.html b/files/ru/web/javascript/reference/functions/arguments/length/index.html new file mode 100644 index 0000000000..4411d266e5 --- /dev/null +++ b/files/ru/web/javascript/reference/functions/arguments/length/index.html @@ -0,0 +1,117 @@ +--- +title: arguments.length +slug: Web/JavaScript/Reference/Functions/arguments/length +translation_of: Web/JavaScript/Reference/Functions/arguments/length +--- +<div>{{jsSidebar("Functions")}}</div> + +<p><strong><code>arguments.length</code></strong> свойство, содержащее число аргументов переданных в функцию.</p> + +<h2 id="Синтаксис">Синтаксис</h2> + +<pre class="syntaxbox">arguments.length</pre> + +<h2 id="Описание">Описание</h2> + +<p>arguments.length свойство содержашее число аргументов переданных в функцию. Оно может быть больше или меньше опреденного параметра count (см. {{jsxref("Function.length")}}).</p> + +<h2 id="Примеры">Примеры</h2> + +<h3 id="Использование_arguments.length"><code>Использование arguments.length</code></h3> + +<p>В этом примере мы определяем функцию, которая может сложить 2 или более чисел вместе.</p> + +<pre class="brush: js">function adder(base /*, n2, ... */) { + base = Number(base); + for (var i = 1; i < arguments.length; i++) { + base += Number(arguments[i]); + } + return base; +} +</pre> + +<h2 id="Спецификации">Спецификации</h2> + +<table class="standard-table"> + <tbody> + <tr> + <th scope="col">Specification</th> + <th scope="col">Status</th> + <th scope="col">Comment</th> + </tr> + <tr> + <td>ECMAScript 1st Edition.</td> + <td>Standard</td> + <td>Initial definition. Implemented in JavaScript 1.1</td> + </tr> + <tr> + <td>{{SpecName('ES5.1', '#sec-10.6', 'Arguments Object')}}</td> + <td>{{Spec2('ES5.1')}}</td> + <td> </td> + </tr> + <tr> + <td>{{SpecName('ES6', '#sec-arguments-exotic-objects', 'Arguments Exotic Objects')}}</td> + <td>{{Spec2('ES6')}}</td> + <td> </td> + </tr> + </tbody> +</table> + +<h2 id="Поддержка_браузерами">Поддержка браузерами</h2> + +<p>{{CompatibilityTable}}</p> + +<div id="compat-desktop"> +<table class="compat-table"> + <tbody> + <tr> + <th>Feature</th> + <th>Chrome</th> + <th>Firefox (Gecko)</th> + <th>Internet Explorer</th> + <th>Opera</th> + <th>Safari</th> + </tr> + <tr> + <td>Basic support</td> + <td>{{CompatVersionUnknown}}</td> + <td>{{CompatVersionUnknown}}</td> + <td>{{CompatVersionUnknown}}</td> + <td>{{CompatVersionUnknown}}</td> + <td>{{CompatVersionUnknown}}</td> + </tr> + </tbody> +</table> +</div> + +<div id="compat-mobile"> +<table class="compat-table"> + <tbody> + <tr> + <th>Feature</th> + <th>Android</th> + <th>Chrome for Android</th> + <th>Firefox Mobile (Gecko)</th> + <th>IE Mobile</th> + <th>Opera Mobile</th> + <th>Safari Mobile</th> + </tr> + <tr> + <td>Basic support</td> + <td>{{CompatVersionUnknown}}</td> + <td>{{CompatVersionUnknown}}</td> + <td>{{CompatVersionUnknown}}</td> + <td>{{CompatVersionUnknown}}</td> + <td>{{CompatVersionUnknown}}</td> + <td>{{CompatVersionUnknown}}</td> + </tr> + </tbody> +</table> +</div> + +<h2 id="Смотрите_также">Смотрите также</h2> + +<ul> + <li>{{jsxref("Function")}}</li> + <li>{{jsxref("Function.length")}}</li> +</ul> diff --git a/files/ru/web/javascript/reference/functions/arrow_functions/index.html b/files/ru/web/javascript/reference/functions/arrow_functions/index.html new file mode 100644 index 0000000000..b903c96852 --- /dev/null +++ b/files/ru/web/javascript/reference/functions/arrow_functions/index.html @@ -0,0 +1,378 @@ +--- +title: Стрелочные функции +slug: Web/JavaScript/Reference/Functions/Arrow_functions +tags: + - ECMAScript6 + - JavaScript + - Функции +translation_of: Web/JavaScript/Reference/Functions/Arrow_functions +--- +<div>{{jsSidebar("Functions")}}</div> + +<h2 id="Сводка">Сводка</h2> + +<p><strong>Выражения стрелочных функций</strong> имеют более короткий синтаксис по сравнению с <a href="/ru/docs/Web/JavaScript/Reference/Operators/function">функциональными выражениями</a> и лексически привязаны к значению <a href="/ru/docs/Web/JavaScript/Reference/Operators/this">this</a> (но не привязаны к собственному <a href="/ru/docs/Web/JavaScript/Reference/Operators/this">this</a>, <a href="https://developer.mozilla.org/ru/docs/Web/JavaScript/Reference/Functions/arguments">arguments</a>, <a href="https://developer.mozilla.org/ru/docs/Web/JavaScript/Reference/Operators/super">super</a>, или <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/new.target">new.target</a>). Выражение стрелочных функций не позволяют задавать имя, поэтому стрелочные функции <a href="/ru/docs/Web/JavaScript/Reference/Global_Objects/Function/name">анонимны</a>, если их ни к чему не присвоить.</p> + +<h2 id="Syntax" name="Syntax">Синтаксис</h2> + +<h3 id="Базовый_синтаксис">Базовый синтаксис</h3> + +<pre class="brush: js">(param1, param2, …, paramN) => { statements } +(param1, param2, …, paramN) => expression +// эквивалентно: (param1, param2, …, paramN) => { return expression; } + +// Круглые скобки не обязательны для единственного параметра: +(singleParam) => { statements } +singleParam => { statements } + +// Функция без параметров нуждается в круглых скобках: +() => { statements } +() => expression +// Эквивалентно: () => { return expression; } +</pre> + +<h3 id="Расширенный_синтаксис">Расширенный синтаксис</h3> + +<pre class="brush: js">// Когда возвращаете литеральное выражение объекта, заключите тело в скобки +params => ({foo: bar}) + +// <a href="https://developer.mozilla.org/ru/docs/Web/JavaScript/Reference/Functions/Rest_parameters">Rest параметры</a> и <a href="https://developer.mozilla.org/ru/docs/Web/JavaScript/Reference/Functions/Default_parameters">параметры по умолчанию</a> поддерживаются +(param1, param2, ...rest) => { statements } +(param1 = defaultValue1, param2, …, paramN = defaultValueN) => { statements } + +// <a href="https://developer.mozilla.org/ru/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment">Деструктуризация</a> тоже поддерживается +var f = ([a, b] = [1, 2], {x: c} = {x: a + b}) => a + b + c; +f(); // 6 +</pre> + +<p>Подробные примеры синтаксиса можно посмотреть <a href="http://wiki.ecmascript.org/doku.php?id=harmony:arrow_function_syntax" title="http://wiki.ecmascript.org/doku.php?id=harmony:arrow_function_syntax">здесь</a>.</p> + +<h2 id="Описание">Описание</h2> + +<p>Смотрите также <a href="https://hacks.mozilla.org/2015/06/es6-in-depth-arrow-functions/">"ES6 In Depth: Arrow functions" on hacks.mozilla.org</a>.</p> + +<p>Два фактора повлияли на появление стрелочных функции: более короткий синтаксис и лексика <code>this</code>.</p> + +<h3 id="Короткие_функции">Короткие функции</h3> + +<p>В некоторых функциональных шаблонах приветствуются более короткие функции. Сравните:</p> + +<pre class="brush: js">var elements = [ + 'Hydrogen', + 'Helium', + 'Lithium', + 'Beryllium' +]; + +elements.map(function(element) { + return element.length; +}); // Это выражение вернет массив [8, 6, 7, 9] + +// Функцию выше можно записать как стрелочную функцию: +elements.map((element) => { + return element.length; +}); // [8, 6, 7, 9] + +// Если единственным оператором в выражении стрелочной функции является return, +// можно удалить return и окружающие фигурные скобки + +elements.map(element => element.length); // [8, 6, 7, 9] + +// В данном случае, поскольку нам нужно только свойство length, мы можем использовать деструктуризированный параметр: +// Обратите внимание, что строка `"length"` соответствует свойству, которое мы хотим получить, +// в то время как `lengthFooBArX` это просто имя переменной, которую можно назвать как вы хотите +elements.map(({ "length": lengthFooBArX }) => lengthFooBArX); // [8, 6, 7, 9] + +// Это задание деструктуризированного параметра может быть записано, как показано ниже. Тем не менее, обратите внимание, +// что нет строки `"length"`, чтобы выбрать, какое свойство мы хотим получить. Вместо этого в качестве свойства, +// которое мы хотим извлечь из объекта, используется само литеральное имя переменной `length` +elements.map(({ length }) => length); // [8, 6, 7, 9] +</pre> + +<h3 id="Отсутствие_связывания_с_this">Отсутствие связывания с <code>this</code></h3> + +<p>До появления стрелочных функций, каждая новая функция имела своё значение <code><a href="/ru/docs/Web/JavaScript/Reference/Operators/this">this</a></code> (новый объект в случае конструктора, undefined в <a href="/ru/docs/Web/JavaScript/Reference/Strict_mode">strict</a> режиме вызова функции, контекст объекта при вызове функции как "метода объекта" и т.д.). Это очень раздражало при использовании объектно-ориентированного стиля программирования.</p> + +<pre class="brush: js">function Person() { + // В конструкторе Person() `this` указывает на себя. + this.age = 0; + + setInterval(function growUp() { + // В нестрогом режиме, в функции growUp() `this` указывает + // на глобальный объект, который отличается от `this`, + // определяемом в конструкторе Person(). + this.age++; + }, 1000); +} + +var p = new Person(); +</pre> + +<p>В ECMAScript 3/5, данная проблема решалась присваиванием значения <code>this</code> переменной:</p> + +<pre class="brush: js">function Person() { + var that = this; + that.age = 0; + + setInterval(function growUp() { + // Функция с обратным вызовом(<a href="/en-US/docs/Mozilla/js-ctypes/Using_js-ctypes/Declaring_and_Using_Callbacks">callback</a>) содержит переменную that, которая + // ссылается на требуемый объект this. + that.age++; + }, 1000); +}</pre> + +<p>Кроме этого, может быть создана <a href="/ru/docs/Web/JavaScript/Reference/Global_Objects/Function/bind">привязанная функция</a>, в которую передаётся требуемое значение <code><a href="/ru/docs/Web/JavaScript/Reference/Operators/this">this</a></code> для функции (функция <code>growUp()</code> в примере выше).</p> + +<p>Стрелочные функции не содержат собственный контекст <code><a href="/ru/docs/Web/JavaScript/Reference/Operators/this">this</a></code>, а используют значение <code><a href="/ru/docs/Web/JavaScript/Reference/Operators/this">this</a></code> окружающего контекста. Поэтому нижеприведенный код работает как предполагалось:</p> + +<pre class="brush: js">function Person(){ + this.age = 0; + + setInterval(() => { + this.age++; // `this` указывает на объект Person + }, 1000); +} + +var p = new Person();</pre> + +<h4 id="Строгий_режим_исполнения">Строгий режим исполнения</h4> + +<p>Поскольку значение <code>this</code> определяется лексикой, правила строгого режима (<a href="/ru/docs/Web/JavaScript/Reference/Strict_mode">strict mode</a>) относительно <code>this</code> игнорируются:</p> + +<pre class="brush: js">var f = () => { 'use strict'; return this; }; +f() === window; // или глобальный объект</pre> + +<p>Все остальные правила строгого режима применяются как обычно.</p> + +<h4 id="Вызов_с_помощью_call_или_apply">Вызов с помощью call или apply</h4> + +<p>Так как значение <code>this</code> определяется лексикой, вызов стрелочных функций с помощью методов <code>call()</code> или <code>apply()</code>, даже если передать аргументы в эти методы, не влияет на значение <code>this</code>:</p> + +<pre class="brush: js">var adder = { + base : 1, + + add : function(a) { + var f = v => v + this.base; + return f(a); + }, + + addThruCall: function(a) { + var f = v => v + this.base; + var b = { + base : 2 + }; + + return f.call(b, a); + } +}; + +console.log(adder.add(1)); // Выводит 2 +console.log(adder.addThruCall(1)); // Всё равно выводит 2 +</pre> + +<h3 id="Не_имеет_собственного_объекта_arguments">Не имеет собственного объекта arguments</h3> + +<p>Стрелочные функции не имеют собственного объекта arguments, поэтому в теле стрелочных функций arguments будет ссылаться на переменную в окружающей области.</p> + +<pre class="brush: js">var arguments = 42; +var arr = () => arguments; + +arr(); // 42 + +function foo() { + var f = (i) => arguments[0] + i; // Неявное связывание ссылки arguments + // стрелочной функции f + // c объектом arguments функции foo + return f(2); +} + +foo(1); // 3</pre> + +<p>В большинстве случаев лучшей заменой объекта arguments в стрелочных функциях являются <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/rest_parameters">rest параметры</a>:</p> + +<pre class="brush: js">function foo() { + var f = (...args) => args[0]; + return f(2); +} + +foo(1); // 2 +</pre> + +<h3 id="Использование_стрелочных_функций_как_методов">Использование стрелочных функций как методов</h3> + +<p>Как показано ранее, стрелочные функции лучше всего подходят для функций без методов. Посмотрим, что будет, когда мы попробуем их использовать как методы:</p> + +<pre class="brush: js">'use strict'; +var obj = { + i: 10, + b: () => console.log(this.i, this), + c: function() { + console.log(this.i, this); + } +} +obj.b(); // prints undefined, Window {...} (или глобальный объект) +obj.c(); // prints 10, Object {...} +</pre> + +<p>Стрелочные функции не объявляют привязку ("bind") их контекста <code>this</code>. Другой пример включает {{jsxref("Object.defineProperty()")}}:</p> + +<pre class="brush: js">'use strict'; +var obj = { + a: 10 +}; + +Object.defineProperty(obj, 'b', { + get: () => { + console.log(this.a, typeof this.a, this); + return this.a + 10; + // представляет глобальный объект 'Window', но 'this.a' возвращает 'undefined' + } +});</pre> + +<h3 id="Использование_оператора_new">Использование оператора <code>new</code></h3> + +<p>Стрелочные функции не могут быть использованы как конструктор и вызовут ошибку при использовании с <code>new</code>:</p> + +<pre class="brush: js">var a = new (function() {}) +// переменной "a" будет присвоено значение экземпляра анонимной функции + +var b = new (() => {}) +// будет выброшено исключениe +// Uncaught TypeError: (intermediate value) is not a constructor</pre> + +<h3 id="Использование_ключевого_слова_yield">Использование ключевого слова <code>yield</code></h3> + +<p>Ключевое слово <code><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/yield">yield</a></code> не может быть использовано в теле стрелочной функции (за исключением случаев, когда разрешается использовать в функциях, вложенных в тело стрелочной функции). Как следствие стрелочные функции не могут быть использованы как генераторы.</p> + +<h2 id="Тело_функции">Тело функции</h2> + +<p>Тело стрелочной функции может иметь краткую (concise body) или блочную (block body) форму.</p> + +<p>Блочная форма не возвращает значение, необходимо явно вернуть значение.</p> + +<pre class="brush: js">var func = x => x * x; // краткий синтаксис, + // неявно возвращает результат +var func = (x, y) => { return x + y; }; // блочный синтаксис, + // явно возвращает результат</pre> + +<h2 id="Возвращаемые_объектные_строки_литералы">Возвращаемые объектные строки (литералы)</h2> + +<p>Помните о том, что возвращаемые <a href="/ru/docs/Web/JavaScript/Guide/Grammar_and_types#Литерал_объекта/">объектные строки</a> используют сокращённый синтаксис: <code>params => {object:literal}</code> будет работать не так, как ожидается.</p> + +<pre class="brush: js">var func = () => { foo: 1 }; +// Вызов func() возвращает undefined! + +var func = () => { foo: function() {} }; +// SyntaxError: function statement requires a name</pre> + +<p>Это происходит потому что код в скобках ({}) распознаётся как цепочка выражений (т.е. <code>foo</code> трактуется как наименование, а не как ключ в объектной строке).</p> + +<p>Не забывайте оборачивать скобками объектные строки.</p> + +<pre class="brush: js">var func = () => ({ foo: 1 });</pre> + +<h2 id="Разрывы_строк">Разрывы строк</h2> + +<p>Стрелочная функция не может содержать разрывы строк между параметрами и стрелкой.</p> + +<pre class="brush: js line-numbers language-js">var func = () + => 1; +// SyntaxError: expected expression, got '=>' +</pre> + +<h2 id="Разбор_порядка_следования">Разбор порядка следования</h2> + +<p>Поскольку стрелка в стрелочной функции не является оператором, то стрелочные функции имеют специальные правила разбора (парсинга), которые взаимодействуют с <a href="/ru/docs/Web/JavaScript/Reference/Operators/Operator_Precedence/">приоритетами операторов</a> иначе, чем в обычных функциях.</p> + +<pre class="brush: js">let callback; + +callback = callback || function() {}; // ok + +callback = callback || () => {}; +// SyntaxError: invalid arrow-function arguments + +callback = callback || (() => {}); // ok +</pre> + +<h2 id="Больше_примеров">Больше примеров</h2> + +<pre class="brush: js">// Пустая стрелочная функция возвращает undefined +let empty = () => {}; + +(() => 'foobar')(); +// Вернёт "foobar" +// (Это Immediately Invoked Function Expression +// смотри '<a href="https://developer.mozilla.org/ru/docs/%D0%A1%D0%BB%D0%BE%D0%B2%D0%B0%D1%80%D1%8C/IIFE">IIFE</a>' в справочнике) + +var simple = a => a > 15 ? 15 : a; +simple(16); // 15 +simple(10); // 10 + +let max = (a, b) => a > b ? a : b; + +// Удобные операции над массивами: filter, map, ... + +var arr = [5, 6, 13, 0, 1, 18, 23]; + +var sum = arr.reduce((a, b) => a + b); +// 66 + +var even = arr.filter(v => v % 2 == 0); +// [6, 0, 18] + +var double = arr.map(v => v * 2); +// [10, 12, 26, 0, 2, 36, 46] + +// Более короткие цепочки promise-ов +promise.then(a => { + // ... +}).then(b => { + // ... +}); + +// Стрелочные функции без параметров, которые визуально легче разбирать +setTimeout( () => { + console.log('Я буду раньше'); + setTimeout( () => { + // deeper code + console.log('Я буду позже'); + }, 1); +}, 1); +</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>{{SpecName('ES6', '#sec-arrow-function-definitions', 'Arrow Function Definitions')}}</td> + <td>{{Spec2('ES6')}}</td> + <td>Изначальное определение.</td> + </tr> + </tbody> +</table> + +<h2 id="Совместимость_с_браузерами">Совместимость с браузерами</h2> + + + +<p>{{Compat("javascript.functions.arrow_functions")}}</p> + +<h3 id="Замечания_для_Firefox">Замечания для Firefox</h3> + +<ul> + <li>Первоначальная реализация стрелочных функций в Firefox автоматически переводила их в строгий режим. Это поведение было изменено в <a href="/en-US/docs/Mozilla/Firefox/Releases/24" title="/en-US/docs/Mozilla/Firefox/Releases/24">Firefox 24</a>. Использование <code>"use strict";</code> стало обязательным.</li> + <li>Стрелочные функции семантически отличаются от нестандартных <a href="/ru/docs/Web/JavaScript/Reference/Operators/Expression_closures">Expression Closures</a>, добавленных в <a href="/en-US/Firefox/Releases/3">Firefox 3</a> (подробности в <a href="/en-US/docs/Web/JavaScript/New_in_JavaScript/1.8">Javascript 1.8</a>); в Expression Closures значение <code>this</code> не привязано лексически.</li> + <li>До <a href="https://developer.mozilla.org/en-US/Firefox/Releases/39">Firefox 39</a>, перенос строки (<code>\n</code>) был ошибочно разрешён после аргументов стрелочной функции. Это было исправлено для соблюдения спецификации ES2015, и код вроде: <code>() \n => {}</code> теперь вызывает {{jsxref("SyntaxError")}} в этой и более поздних версиях.</li> +</ul> + +<h2 id="See_also">See also</h2> + +<ul> + <li><a href="https://hacks.mozilla.org/2015/06/es6-in-depth-arrow-functions/">"ES6 In Depth: Arrow functions" on hacks.mozilla.org</a></li> +</ul> diff --git a/files/ru/web/javascript/reference/functions/default_parameters/index.html b/files/ru/web/javascript/reference/functions/default_parameters/index.html new file mode 100644 index 0000000000..2e6568b816 --- /dev/null +++ b/files/ru/web/javascript/reference/functions/default_parameters/index.html @@ -0,0 +1,217 @@ +--- +title: Параметры по умолчанию +slug: Web/JavaScript/Reference/Functions/Default_parameters +tags: + - ECMAScript6 + - JavaScript + - Функции + - Экспериментальный +translation_of: Web/JavaScript/Reference/Functions/Default_parameters +--- +<div>{{jsSidebar("Functions")}}</div> + +<p><strong>Параметры по умолчанию</strong> позволяют задавать формальным параметрам функции значения по умолчанию в случае, если функция вызвана без аргументов, или если параметру явным образом передано значение <code>undefined</code>.</p> + +<p>{{EmbedInteractiveExample("pages/js/functions-default.html")}}</p> + +<h2 id="Syntax" name="Syntax">Синтаксис</h2> + +<pre class="syntaxbox">function [<em>name</em>]([<em>param1</em>[ = defaultValue1 ][, ..., <em>paramN</em>[ = defaultValueN ]]]) { + <em>statements</em> +} +</pre> + +<h2 id="Example" name="Example">Описание</h2> + +<p>В JavaScript параметры функции, которым при ее вызове не передаются значения, принимают по умолчанию значение <code>{{jsxref("undefined")}}</code>. Однако в некоторых случаях может быть полезно задать иное значение по умолчанию. Именно для таких случаев предназначены параметры по умолчанию.</p> + +<p>В прошлом для проверки параметров и задания их значений по умолчанию использовался код в теле функции, в котором проверялось, не равны ли значения параметров <code>undefined</code>.</p> + +<p>В приведённом ниже примере, в случае если при вызове функции значение для параметра <code>b</code> не передавалось, его значением становилось <code>undefined</code>, и результатом вычисления <code>a * b</code> в функции <code>multiply</code> получалось значение <code>NaN</code>.</p> + +<pre class="brush: js">function multiply(a, b) { + return a * b; +} + +multiply(5, 2); // 10 +multiply(5); // NaN !</pre> + +<p>Чтобы такого не происходило, в теле функции использовался код подобный тому, что находится во второй строчке, где в случае, если функция <code>multiply</code> вызывалась только c одним аргументом, параметру <code>b</code> присваивалось значение <code>1</code>:</p> + +<pre class="brush: js">function multiply(a, b) { + b = typeof b !== 'undefined' ? b : 1; + return a*b; +} + +multiply(5, 2); // 10 +multiply(5); // 5 +</pre> + +<p>С появлением в ES2015 параметров по умолчанию стало возможным обходиться без проверки параметров в теле функции. Так, в приведенном выше примере достаточно в заголовке функции указать <code>1</code> в качестве значения по умолчанию для параметра <code>b</code>:</p> + +<pre class="brush: js">function multiply(a, b = 1) { + return a*b; +} + +multiply(5, 2); // 10 +multiply(5); // 5 +multiply(5, undefined); // 5</pre> + +<h2 id="Примеры">Примеры</h2> + +<h3 id="Передача_значения_undefined_в_сравнении_с_передачей_других_ложных_значений">Передача значения <code>undefined</code> в сравнении с передачей других "ложных" значений</h3> + +<p>Значение по умолчанию присваивается формальному параметру только если при вызове функции значение для данного параметра не было передано или было явным образом передано <code>undefined</code>. Если формальному параметру при вызове передано любое значение, отличное от <code>undefined</code>, в том числе одно из <a href="/ru/docs/%D0%A1%D0%BB%D0%BE%D0%B2%D0%B0%D1%80%D1%8C/Falsy">"ложных"</a> значений, таких как <code>false</code>, <code>0</code>, <code>""</code>, <code>''</code>, <code>``</code>, <code>null</code>, <code>NaN</code>, то в этом случае значение по умолчанию присвоено параметру не будет. Это иллюстрирует следующий пример:</p> + +<pre class="brush: js">function test(num = 1) { + console.log(typeof num); +} + +// num не прередано, или передано undefined: +test(); // 'number' (num получил значение 1) +test(undefined); // 'number' (и здесь num получил значение 1) + +// num передано значение null или другое "ложное" значение: +test(''); // 'string' (num получил значение '') +test(null); // 'object' (num получил значение null) +</pre> + +<h3 id="Параметры_по_умолчанию_вычисляются_в_момент_вызова_функции">Параметры по умолчанию вычисляются в момент вызова функции</h3> + +<p>В Javascript параметры по умолчанию вычисляются в момент вызова функции. В отличие от языка Python, при каждом вызове функции создается новое лексическое окружение функции.</p> + +<pre class="brush: js">function append(value, array = []) { + array.push(value); + return array; +} + +append(1); // [1] +append(2); // [2], а не [1, 2] + +</pre> + +<p>Это верно и для функций, и для переменных:</p> + +<pre class="brush: js">function callSomething(thing = something()) { + return thing; +} + +let numberOfTimesCalled = 0; +function something() { + numberOfTimesCalled += 1; + return numberOfTimesCalled; +} + +callSomething(); // 1 +callSomething(); // 2 +</pre> + +<h3 id="Параметры_по_умолчанию_доступны_в_следующих_параметрах_по_умолчанию">Параметры по умолчанию доступны в следующих параметрах по умолчанию</h3> + +<p>В параметрах по умолчанию можно использовать значения предыдущих (расположеннных левее в списке) параметров:</p> + +<pre class="brush: js">function greet(name, greeting, message = greeting + ' ' + name) { + return [name, greeting, message]; +} + +greet('David', 'Hi'); // ["David", "Hi", "Hi David"] +greet('David', 'Hi', 'Happy Birthday!'); // ["David", "Hi", "Happy Birthday!"]</pre> + +<p>Следующий пример пример еще раз иллюстирует эту возможность, а также позволяет еще раз сравнить два способа достижения одного и того же результата: с использованием инициализации параметров по умолчанию и без ее использования:</p> + +<pre class="brush: js">function go() { + return ":P" +} + +function withDefaults(a, b = 5, c = b, d = go(), e = this, + f = arguments, g = this.value) { + return [a,b,c,d,e,f,g]; +} +function withoutDefaults(a, b, c, d, e, f, g){ + switch(arguments.length){ + case 0: + a + case 1: + b = 5 + case 2: + c = b + case 3: + d = go(); + case 4: + e = this + case 5: + f = arguments + case 6: + g = this.value; + default: + } + return [a,b,c,d,e,f,g]; +} + +withDefaults.call({value:"=^_^="}); +// [undefined, 5, 5, ":P", {value:"=^_^="}, arguments, "=^_^="] + + +withoutDefaults.call({value:"=^_^="}); +// [undefined, 5, 5, ":P", {value:"=^_^="}, arguments, "=^_^="] +</pre> + +<h3 id="Инициализация_с_помощью_функций_определяемых_в_теле_функции">Инициализация с помощью функций, определяемых в теле функции</h3> + +<p>Начиная с версии Gecko 33 {{geckoRelease(33)}} функции, определяемые в теле самой функции, не могут быть использованы для инициализации параметров по умолчанию; попытка это сделать приведет к ошибке {{jsxref("ReferenceError")}}. Параметры по умолчанию всегда вычисляются до обработки описаний функций, определяемых в теле функции.</p> + +<pre class="brush: js">// Вызовет ошибку ReferenceError! +function f(a = go()) { + function go(){return ":P"} +} +f(); // ReferenceError: go is not defined +</pre> + +<h3 id="Параметры_без_инициализации_следующие_после_инициализируемых_параметров">Параметры без инициализации, следующие после инициализируемых параметров</h3> + +<p>До появления версии Gecko 26 {{geckoRelease(26)}}, следующий код приводил к {{jsxref("SyntaxError")}}. Это было исправлено в {{bug(777060)}} и с тех пор работает корректно. Аргументы, передаваемые при вызове функции, становятся значениями формальных параметров независимо от наличия у последних инициализации по умолчанию, а также независимо от присутствия у функции других параметров, находящихся правее в списке параметров и не имеющих инициализации.</p> + +<pre class="brush: js">function f(x=1, y) { + return [x, y]; +} + +f(); // [1, undefined]; +f(2); // [2, undefined]; +</pre> + +<h3 id="Инициализация_по_умолчанию_деструктурированных_параметров">Инициализация по умолчанию деструктурированных параметров</h3> + +<p>При инициализации параметров по умолчанию можно использовать синтаксическую конструкцию деструктурирующего присваивания:</p> + +<pre class="brush: js">function f([x, y] = [1, 2], {z: z} = {z: 3}) { + return x + y + z; +} + +f(); // 6</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>{{SpecName('ES6', '#sec-function-definitions', 'Определение функций')}}</td> + <td>{{Spec2('ES6')}}</td> + <td>Изначальное определение.</td> + </tr> + </tbody> +</table> + +<h2 id="Совместимость_с_браузерами">Совместимость с браузерами</h2> + +<p>{{Compat("javascript.functions.default_parameters")}}</p> + +<h2 id="See_also" name="See_also">Смотрите также</h2> + +<ul> + <li><a href="http://wiki.ecmascript.org/doku.php?id=harmony:parameter_default_values" rel="external">Оригинальное предложение на ecmascript.org</a></li> +</ul> diff --git a/files/ru/web/javascript/reference/functions/get/index.html b/files/ru/web/javascript/reference/functions/get/index.html new file mode 100644 index 0000000000..9e2c329c8e --- /dev/null +++ b/files/ru/web/javascript/reference/functions/get/index.html @@ -0,0 +1,180 @@ +--- +title: getter +slug: Web/JavaScript/Reference/Functions/get +tags: + - геттер +translation_of: Web/JavaScript/Reference/Functions/get +--- +<div>{{jsSidebar("Functions")}}</div> + +<p>Синтаксис <strong><code>get</code></strong> связывает свойство объекта с функцией, которая будет вызываться при обращении к этому свойству.</p> + +<div>{{EmbedInteractiveExample("pages/js/functions-getter.html")}}</div> + +<p class="hidden">Исходный код этого интерактивного примера хранится в GitHub репозитории. Если вы хотите внести свой вклад в проект интерактивных примеров, пожалуйста, клонируйте <a href="https://github.com/mdn/interactive-examples">https://github.com/mdn/interactive-examples</a> и отправьте нам PR запрос.</p> + +<h2 id="Синтаксис">Синтаксис</h2> + +<pre class="syntaxbox">{get <var>prop</var>() { ... } } +{get [<var>expression</var>]() { ... } }</pre> + +<h3 id="Параметры">Параметры</h3> + +<dl> + <dt><code><var>prop</var></code></dt> + <dd>Имя свойства для привязывания к заданной функции.</dd> + <dt><code><var>expression</var></code></dt> + <dd>Начиная с ECMAScript 6, Вы также можете использовать выражения для вычисляемого имени свойства для привязки к заданной функции.</dd> +</dl> + +<h2 id="Описание">Описание</h2> + +<p>Иногда желательно разрешить доступ к свойству, которое возвращает динамически вычисляемое значение, или Вы можете захотеть отражать состояние внутренней переменной без необходимости использования явных вызовов методов. В JavaScript, это можно реализовать при помощи использования <em>геттера</em>.</p> + +<p>Невозможно сделать так, чтобы геттер был привязан к свойству и одновременно чтобы это свойство действительно содержало значение, хотя можно использовать геттер и сеттер в сочетании, чтобы создать тип псевдо-свойство.</p> + +<p>Учтите следующее при работе с синтаксисом <code>get</code>:</p> + +<div> +<ul> + <li>Он может иметь идентификатор, который является либо числом, либо строкой;</li> + <li>Он должен иметь ровно 0 параметров (смотрите <a class="external" href="http://whereswalden.com/2010/08/22/incompatible-es5-change-literal-getter-and-setter-functions-must-now-have-exactly-zero-or-one-arguments/" rel="external nofollow">Incompatible <abbr title="ECMAScript 5th edition">ES5</abbr> change: literal getter and setter functions must now have exactly zero or one arguments</a> для доп. информации);</li> + <li>Он не должен появляться в объектном литерале вместе с другим get или через ввод данных для того же свойства (<code>{ get x() { }, get x() { } }</code> и <code>{ x: ..., get x() { } }</code> запрещены).</li> +</ul> +</div> + +<p>Геттер можно удалить при помощи оператора <code><a href="/en-US/docs/Web/JavaScript/Reference/Operators/delete" title="en/Core_JavaScript_1.5_Reference/Operators/Special_Operators/delete_Operator">delete</a></code>.</p> + +<h2 id="Примеры">Примеры</h2> + +<h3 id="Определение_геттера_на_новом_объекте_в_момент_инициализации_этого_объекта">Определение геттера на новом объекте в момент инициализации этого объекта</h3> + +<p>Ниже создается псевдо-свойство <code>latest</code> для объекта <code>obj</code>, который выведет последний элемент массива в консоль лог.</p> + +<pre class="brush: js">const obj = { + log: ['example','test'], + get latest() { + if (this.log.length === 0) return undefined; + return this.log[this.log.length - 1]; + } +} +console.log(obj.latest); // "test" +</pre> + +<p>Обратите внимание, что попытка присвоить значение <code>latest</code> не изменит его.</p> + +<h3 id="Удаление_геттера_оператором_delete">Удаление геттера оператором delete</h3> + +<p><code><font face="Open Sans, Arial, sans-serif">Если Вы хотите удалить геттер, используйте </font><a href="/en-US/docs/Web/JavaScript/Reference/Operators/delete">delete</a></code>:</p> + +<pre class="brush: js">delete <var>obj</var>.latest;</pre> + +<h3 id="Определение_геттера_на_уже_существующих_объектах_с_помощью_defineProperty">Определение геттера на уже существующих объектах с помощью <code>defineProperty</code></h3> + +<p>Для добавления геттера к существующему объекту в любое время используйте <a class="external" href="https://developer.mozilla.org/ru/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperty" rel="external nofollow">Object.defineProperty()</a>.</p> + +<pre class="brush: js">const o = {a: 0}; + +Object.defineProperty(o, 'b', { get: function() { return this.a + 1; } }); + +console.log(o.b) // Runs the getter, which yields a + 1 (which is 1) +</pre> + +<h3 id="Использование_вычисляемого_именованного_свойства">Использование вычисляемого именованного свойства</h3> + +<div class="note"> +<p><strong>Примечание:</strong> Вычисляемые свойства являются экспериментальной технологией, частью предложений спецификации ECMAScript 6, и массовой поддержки браузерами пока нет. Код ниже вызовет синтаксическую ошибку в неподдерживаемых средах.</p> +</div> + +<pre class="brush: js">var expr = "foo"; + +var obj = { + get [expr]() { return "bar"; } +}; + +console.log(obj.foo); // "bar"</pre> + +<h3 id="Умные_самостоятельно_перезаписывающиеся_ленивые_геттеры">Умные / самостоятельно перезаписывающиеся/ ленивые геттеры</h3> + +<p>Геттеры дают нам возможность определять свойство объекта , но они не вычисляют значение этого свойства до тех пор, пока оно не станет доступно. Геттер откладывает стоимость вычисления значения до тех пор, пока это значение не станет нужно, и если оно никогда не понадобится, то вы никогда не заплатите.</p> + +<p>Дополнительная техника оптимизации заключается в том, чтобы лениться или откладывать вычисление значения свойства и кэшировать его для дальнейшего доступа. Так поступают <strong>умные или <a href="https://en.wikipedia.org/wiki/Memoization">запоминающие</a> геттеры</strong>. Значение вычисляется в первый раз при вызове геттера и затем сохраняется в кэше так, что последующие обращения будут возвращать кэшированные значения без его пересчета. Это полезно в следующих ситуациях:</p> + +<ul> + <li>Если вычисление значения свойства дорого (занимает много оперативной памяти или процессорного времени, порождает рабочий поток, получает удаленный файл, и т. д.).</li> + <li>Если сейчас это значение не нужно. Оно будет использоваться позже, или в некоторых случаях оно не используется вообще.</li> + <li>Если оно используется, к нему будут обращаться несколько раз, и нет необходимости его пересчитывать, так как значение не будет изменено, или не должно пересчитываться.</li> +</ul> + +<p>Значит, Вам не нужно использовать ленивый геттер для свойства, значение которого Вы собираетесь менять потому, что геттер не будет пересчитывать значение.</p> + +<p>В следующем примере у объекта есть геттер как собственное свойство. При получении свойства, свойство удаляется из объекта и вновь добавляется, но в этот раз неявно, как свойство с данными. В итоге значение возвращается.</p> + +<pre class="brush: js">get notifier() { + delete this.notifier; + return this.notifier = document.getElementById("bookmarked-notification-anchor"); +},</pre> + +<p>Для Firefox смотрите также модуль XPCOMUtils.jsm , который определяет функцию <code><a href="/en-US/docs/Mozilla/JavaScript_code_modules/XPCOMUtils.jsm#defineLazyGetter()">defineLazyGetter()</a></code>.</p> + +<h3 id="get_и_defineProperty"><code>get</code> и <code>defineProperty</code></h3> + +<p>Использование ключевого слова <code>get</code> и {{jsxref("Object.defineProperty()")}} дает похожие результаты, но при использовании в {{jsxref("classes")}} между ними есть тонкая разница.</p> + +<p>При использовании <code>get</code> свойство будет определено в прототипе объекта, в то время, как при использовании {{jsxref ("Object.defineProperty ()")}} свойство будет определено в экземпляре, к которому применяется.</p> + +<pre class="brush: js">class Example { + get hello() { + return 'world'; + } +} + +const obj = new Example(); +console.log(obj.hello); +// "world" +console.log(Object.getOwnPropertyDescriptor(obj, 'hello')); +// undefined +console.log(Object.getOwnPropertyDescriptor(Object.getPrototypeOf(obj), 'hello')); +// { configurable: true, enumerable: false, get: function get hello() { return 'world'; }, set: undefined }</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>{{SpecName('ES5.1', '#sec-11.1.5', 'Object Initializer')}}</td> + <td>{{Spec2('ES5.1')}}</td> + <td>Первоначальное определение.</td> + </tr> + <tr> + <td>{{SpecName('ES6', '#sec-method-definitions', 'Method definitions')}}</td> + <td>{{Spec2('ES6')}}</td> + <td>Добавлено вычисляемое именное свойство.</td> + </tr> + <tr> + <td>{{SpecName('ESDraft', '#sec-method-definitions', 'Method definitions')}}</td> + <td>{{Spec2('ESDraft')}}</td> + <td></td> + </tr> + </tbody> +</table> + +<h2 id="Browser_compatibility" name="Browser_compatibility">Совместимость с браузерами</h2> + +<p>{{Compat("javascript.functions.get")}}</p> + +<h2 id="Смотрите_также">Смотрите также</h2> + +<ul> + <li><a href="/en-US/docs/Web/JavaScript/Reference/Functions/set">сеттер</a></li> + <li>{{jsxref("Operators/delete", "delete")}}</li> + <li>{{jsxref("Object.defineProperty()")}}</li> + <li>{{jsxref("Object.defineGetter", "__defineGetter__")}}</li> + <li>{{jsxref("Object.defineSetter", "__defineSetter__")}}</li> + <li><a href="/en-US/docs/Web/JavaScript/Guide/Working_with_Objects#Defining_getters_and_setters">Defining Getters and Setters</a> in JavaScript Guide</li> +</ul> diff --git a/files/ru/web/javascript/reference/functions/index.html b/files/ru/web/javascript/reference/functions/index.html new file mode 100644 index 0000000000..0353eb3b84 --- /dev/null +++ b/files/ru/web/javascript/reference/functions/index.html @@ -0,0 +1,483 @@ +--- +title: Функции +slug: Web/JavaScript/Reference/Functions +tags: + - Функции + - Функция +translation_of: Web/JavaScript/Reference/Functions +--- +<div>{{jsSidebar("Functions")}}</div> + +<h2 id="Summary" name="Summary">Сводка</h2> + +<p>В общем случае, функция — это "подпрограмма", которую можно <em>вызывать</em> из внешнего (или внутренного, в случае рекурсии) по отношению к функции кода. Как и сама программа, функция состоит из последовательности инструкций, называемой <em>телом функции.</em> Значения могут быть <em>переданы</em> в функцию, а функция <em>вернёт</em> значение.</p> + +<p>В JavaScript функции являются объектами первого класса, то есть: они являются объектами и с ними можно взаимодействовать и передавать их точно так же как любой другой объект. Если быть точным, функции — это обьекты <code><a href="ru/docs/Web/JavaScript/Reference/Global_Objects/Function">Function</a></code>.</p> + +<p>Больше подробностей и примеров можно найти в <a href="/ru/docs/Web/JavaScript/Guide/Functions">руководстве по функциям в JavaScript</a>.</p> + +<h2 id="Описание">Описание</h2> + +<p>Каждая функция в JavaScript — это объект Function. О свойствах и методах объектов Function можно прочитать в статье {{jsxref("Function")}}.</p> + +<p>Функции — это не процедуры. Функция всегда возвращает значение, а процедура может возвращать, а может не возвращать.</p> + +<p>Чтобы вернуть значение, отличное от значения по умолчанию, в функции должна быть инструкция <code><a href="/ru/docs/Web/JavaScript/Reference/Statements/return">return</a></code>, которая указывает, что именно нужно вернуть. Функция без него вернёт значение по умолчанию. В случае <a href="/ru/docs/Web/JavaScript/Reference/Global_Objects/Object/constructor">конструктора</a>, вызванного с ключевым словом <code><a href="/ru/docs/Web/JavaScript/Reference/Operators/new">new</a>, </code>значение по умолчанию — это значение его параметра <code>this</code>. Для остальных функций значением по умолчанию будет <code>undefined</code>.</p> + +<p>Параметры вызова функции называются <em>аргументами</em> функции. Аргументы передаются в функцию <em>по значению</em>. Если функция изменяет значение аргумента, это изменение не отражается на глобальном состоянии или вызывающей функции. Однако ссылки на объекты — это тоже значения, и они отличаются тем, что если функция изменяет свойства объекта по ссылке, это изменение видно снаружи функции, как показано в примере ниже.</p> + +<pre class="brush: js">/* Объявляем функцию 'myFunc' */ +function myFunc(theObject) { + theObject.brand = "Toyota"; + } + + /* + * Объявляем переменную 'mycar'; + * создаём и инициализируем новый Object; + * приравниваем 'mycar' к ссылке на него + */ + var mycar = { + brand: "Honda", + model: "Accord", + year: 1998 + }; + + /* Выведет 'Honda' */ + console.log(mycar.brand); + + /* Передаём ссылку на объект в функцию */ + myFunc(mycar); + + /* + * Выведет 'Toyota', так как значение свойства 'brand' + * было изменено внутри функции. + */ + console.log(mycar.brand); +</pre> + +<p><a href="/ru/docs/Web/JavaScript/Reference/Operators/this"><code>Ключевое слово this</code></a> не ссылается на функцию, которая выполняется в данный момент, поэтому вы должны обращаться к объектами Function по имени, даже внутри тела самой функции.</p> + +<h2 id="Defining_functions" name="Defining_functions">Определение функций</h2> + +<p>Есть несколько способов определить функцию:</p> + +<h3 id="The_function_declaration_.28function_statement.29" name="The_function_declaration_.28function_statement.29">Объявление функции (инструкция <code>function</code>)</h3> + +<p>Специальный синтаксис для объявления функций (более подробно: <a href="/ru/docs/Web/JavaScript/Reference/Statements/function">function statement</a>):</p> + +<pre>function <em>name</em>([<em>param</em>[, <em>param</em>[, ... <em>param</em>]]]) { + <em>statements</em> +} +</pre> + +<dl> + <dt><code>name</code></dt> + <dd>Имя функции.</dd> +</dl> + +<dl> + <dt><code>param</code></dt> + <dd>Имя аргумента, передаваемого в функцию. У функции может быть не более 255 аргументов.</dd> +</dl> + +<dl> + <dt><code>statements</code></dt> + <dd>Инструкции, из которых состоит тело функции.</dd> +</dl> + +<h3 id="The_function_expression_.28function_operator.29" name="The_function_expression_.28function_operator.29">Функция-выражение (оператор <code>function</code>)</h3> + +<p>Функция-выражение похожа на определение функции и имеет такой же синтаксис (более подробно: <a href="/ru/docs/Web/JavaScript/Reference/Operators/function">function operator</a>):</p> + +<pre>function [<em>name</em>]([<em>param</em>] [, <em>param</em>] [..., <em>param</em>]) { + <em>statements</em> +} +</pre> + +<dl> + <dt><code>name</code></dt> + <dd>Имя функции. Может быть не указано, в таком случае функция становится анонимной.</dd> +</dl> + +<dl> + <dt><code>param</code></dt> + <dd>Имя аргумента, передаваемого в функцию. У функции может быть не более 255 аргументов.</dd> + <dt><code>statements</code></dt> + <dd>Инструкции, из которых состоит тело функции.</dd> +</dl> + +<h3 id="Стрелочная_функция-выражение_(>)">Стрелочная функция-выражение (=>)</h3> + +<div class="note"> +<p><strong>Заметка:</strong> стрелочные функции являются экспериментальной технологией<em>,</em> частью спецификации ECMAScript 6 и пока что не поддерживаются всеми браузерами.</p> +</div> + +<p>Стрелочные функции отличаются более кратким синтаксисом и тем, что они лексически связывают значение своего <code>this (подробнее об этом в статье <a href="/ru/docs/Web/JavaScript/Reference/Functions/Arrow_functions">Стрелочные функции</a>):</code></p> + +<pre>([param] [, param]) => { + statements +} + +param => expression +</pre> + +<dl> + <dt><code>param</code></dt> + <dd>Имя параметра. Если параметров нет, вместо них нужно поставить (). Если параметров больше одного, их также нужно заключить в ().</dd> + <dt><code>statements or expression</code></dt> + <dd>Если инструкций несколько, их нужно заключить в {}. Для одного выражения фигурных скобок не требуется, а результат этого выражения будет возвращён функцией (то есть<code> функция x => 3 + 8 вернёт 11).</code><code> </code></dd> +</dl> + +<h3 id="The_Function_constructor" name="The_Function_constructor">Конструктор <code>Function</code></h3> + +<div class="note"> +<p><strong>Заметка:</strong> Использовать конструктор Function не рекомендуется, так как он принимает тело функции в виде строки, а это может помешать оптимизациям, которые выполняют движки JavaScript, а также привести к другим проблемам.</p> +</div> + +<p>Объекты {{jsxref("Function")}} можно создавать с помощью оператора <code>new </code>(как и любые другие объекты):</p> + +<pre>new Function (<em>arg1</em>, <em>arg2</em>, ... <em>argN</em>, <em>functionBody</em>) +</pre> + +<dl> + <dt><code>arg1, arg2, ... arg<em>N</em></code></dt> + <dd>Ноль или больше имён параметров функции. Имя должно быть строкой, содержащей валидный идентификатор JavaScript. Если параметров несколько, они должны быть разделены запятыми. Например: "<code>x</code>", "<code>theValue</code>", или "<code>a,b</code>".</dd> +</dl> + +<dl> + <dt><code>functionBody</code></dt> + <dd>Инструкции, из которых состоит тело функции.</dd> +</dl> + +<p>Конструктор <code>Function</code> можно вызывать и без оператора <code>new,</code> эффект будет тем же.</p> + +<h2 id="Параметры_функции">Параметры функции</h2> + +<div class="note"> +<p><strong>Примечание:</strong> Оставшиеся параметры и параметры по умолчанию <em>— это экспериментальная </em>технология, часть спецификации ECMAScript 6, и они пока ещё не получили широкой поддержки среди браузеров.</p> +</div> + +<h3 id="Параметры_по_умолчанию">Параметры по умолчанию</h3> + +<p>Параметры функции по умолчанию позволяют инициалазировать формальные параметры со значениями по умолчанию, если им не было передано значение, или было передано <code>undefined</code>. Подробнее о них можно узнать в статье <a href="/ru/docs/Web/JavaScript/Reference/Functions/Default_parameters">Параметры по умолчанию</a>.</p> + +<h3 id="Оставшиеся_параметры">Оставшиеся параметры</h3> + +<p>Синтаксис оставшихся параметров позволяет передать бесконечное число аргументов как массив. Подробности можно найти в статье <a href="/ru/docs/Web/JavaScript/Reference/Functions/rest_parameters">Оставшиеся параметры</a>.</p> + +<h2 id="The_arguments_object" name="The_arguments_object">Объект <code>arguments</code></h2> + +<p>Внутри функции получить доступ к её аргументам можно через объект <a href="/ru/docs/Web/JavaScript/Reference/Functions/arguments">arguments</a>.</p> + +<ul> + <li><code><a href="/en-US/docs/JavaScript/Reference/Functions_and_function_scope/arguments">arguments</a></code>: Объект, похожий на массив и содержащий все аргументы, переданные в текущую функцию.</li> + <li><code><a href="/en-US/docs/JavaScript/Reference/Functions_and_function_scope/arguments/callee">arguments.callee</a></code> {{Deprecated_inline}}: Функция, исполняемая в текущий момент.</li> + <li><code><a href="/en-US/docs/JavaScript/Reference/Functions_and_function_scope/arguments/caller">arguments.caller</a></code> {{Obsolete_inline}} : Функция, которая вызвала текущую функцию.</li> + <li><code><a href="/en-US/docs/JavaScript/Reference/Functions_and_function_scope/arguments/length">arguments.length</a></code>: Число аргументов, переданных в функцию.</li> +</ul> + +<h2 id="Определение_методов">Определение методов</h2> + +<h3 id="Геттеры_и_сеттеры">Геттеры и сеттеры</h3> + +<p>Можно определять геттеры (методы для чтения) и сеттеры (методы для изменения) для любого встроенного или пользовательского объекта, который поддерживает добавление новых свойств. Для этого используется синтаксис литерала объекта.</p> + +<dl> + <dt><a href="/en-US/docs/Web/JavaScript/Reference/Functions/get">get</a></dt> + <dd>Связывает свойство объекта с функцией, которая будет вызвана при обращении к свойству.</dd> + <dt><a href="/en-US/docs/Web/JavaScript/Reference/Functions/set">set</a></dt> + <dd>Связывает свойство объекта с функцией, которая будет вызвана при попытке изменения свойства.</dd> +</dl> + +<h3 id="Синтаксис_определения_методов">Синтаксис определения методов</h3> + +<div class="note"> +<p><strong>Примечание:</strong> <em>Определение методов — это экспериментальная </em>технология, часть спецификации ECMAScript 6, и она пока ещё не получила широкой поддержки среди браузеров.</p> +</div> + +<p>Начиная с ECMAScript 6, можно определять собственные методы, использу более краткий синтаксис, похожий на геттеры и сеттеры. Более подробно — в статье <a href="/ru/docs/Web/JavaScript/Reference/Functions/Method_definitions">Определение методов.</a></p> + +<pre class="brush: js">var obj = { + foo() {}, + bar() {} +};</pre> + +<h2 id="Function_constructor_vs._function_declaration_vs._function_expression" name="Function_constructor_vs._function_declaration_vs._function_expression">Сравнение конструкторов <code>Function</code> с объявлением функций и функциями-выражениями</h2> + +<p>Посмотрите на следующие примеры:</p> + +<p>Функция, определённая через конструктор <code>Function</code> и приравненная к переменной <code>multiply:</code></p> + +<pre class="brush: js">var multiply = new Function("x", "y", "return x * y");</pre> + +<p>Объявление функции multiply:</p> + +<pre class="brush: js">function multiply(x, y) { + return x * y; +} +</pre> + +<p>Анонимная функция-выражение, приравненная к переменной<code> multiply:</code></p> + +<pre class="brush: js">var multiply = function(x, y) { + return x * y; +}; +</pre> + +<p><em>Функция-выражение</em> с именем <code>func_name</code>, приравненное к переменной<code> multiply:</code></p> + +<pre class="brush: js">var multiply = function func_name(x, y) { + return x * y; +}; +</pre> + +<h3 id="Отличия">Отличия</h3> + +<p>Во всех случаях результат примерно одинаков, но есть несколько нюансов:</p> + +<p>Имя функции и переменная, к которой функция приравнена — это не одно и то же. Имя функции нельзя менять, а вот переменной, к которой приравнена функция, можно дать другое значение. В случае функции-выражения с именем, это имя может быть использовано только внутри самой функции. При попытке использовать его снаружи возникнет ошибка (а если ранее была объявлена переменная с таким именем, будет возвращено <code>undefined</code>). Например:</p> + +<pre class="brush: js">var y = function x() {}; +alert(x); // выкинет ошибку +</pre> + +<p>Также имя фукнции-выражения проявляется, если сериализовать функцию через метод <a href="/ru/docs/Web/JavaScript/Reference/Global_Objects/Function/toString">Function.toString.</a></p> + +<p>А вот переменная, к которой функция приравнена, ограничена только собственной областью видимости, которая включает ту область, где функция была объявлена.</p> + +<p>Как показано в четвёртом примере, имя функции может отличаться от имени переменной, к которой функция приравнена, эти имена никак не связаны. Объявление функции (function declaration) также создаёт и переменную с именем, аналогичным имени функции. Таким образом:</p> + +<ol> + <li>Если функция определена с помощью функции-выражения (function expression), её имя доступно только внутри самой функции.</li> + <li>Если функция объявлена (function declaration), её имя доступно в той области видимости, где функция была определена.</li> +</ol> + +<p>У функции, определённой с помощью '<code>new Function'</code>, нет имени. Однако, в JavaScript движке <a href="/en-US/docs/Mozilla/Projects/SpiderMonkey">SpiderMonkey</a>, сериализованное представление функции отображается так, как будто оно имеет имя "anonymous". Например, , <code>alert(new Function())</code> выдаст:</p> + +<pre class="brush: js">function anonymous() { +} +</pre> + +<p>Так как на самом деле у функции нет имени, переменную <code>anonymous</code> нельзя использовать внутри функции. Например, следующий пример выкинет ошибку:</p> + +<pre class="brush: js">var foo = new Function("alert(anonymous);"); +foo(); +</pre> + +<p>В отличии от функций, определённых через функцию-выражение или конструктор <code>Function</code>, функция, определённая через объявление, может быть использована перед тем, как была определена. Например:</p> + +<pre class="brush: js">foo(); // выведет FOO! +function foo() { + alert('FOO!'); +} +</pre> + +<p>Функция, определённая через функцию-выражение, наследует текущую область видимости, то есть создаёт замыкание. А вот функция, созданная с помощью конструктора <code>Function</code>, не наследует ничего, кроме глобальной области видимости (её наследуют вообще все функции).</p> + +<p>Функции, определённые через функцию-выражение и объявление функции парсятся только один раз, в отличиии от функций, созданных с помощью конструктора. То есть строка, которая передаётся в конструктор <code>Function</code>, парсится при каждом вызове конструктора. И хотя функция-выражение каждый раз создаёт замыкание, тело функции при этом не парсится, и получается, что функции-выражение всё равно быстрее, чем "<code>new Function(...)</code>". Поэтому конструктора <code>Function</code> в большинстве случаев стоит избегать, если это возможно.</p> + +<p>Стоит отметить, что функции-выражения и объявления функций внутри функции, созданной при парсинге конструктора <code>Function</code>, парсятся только один раз. Например:</p> + +<pre class="brush: js">var foo = (new Function("var bar = \'FOO!\';\nreturn(function() {\n\talert(bar);\n});"))(); +foo(); // "function() {\n\talert(bar);\n}" Эта часть строки, составляющей тело функции, не парсится во второй раз.</pre> + +<p>Объявление функции можно очень легко (и часто случайно) превратить в функцию-выражение. Объявление функции перестаёт быть таковым, если оно:</p> + +<ul> + <li>становится частью выражения</li> + <li>не является "исходным элементом" функции или файла. Исходный элемент - это не вложенный элемент внутри функции или скрипта:</li> +</ul> + +<pre class="brush: js">var x = 0; // исходный элемент +if (x == 0) { // исходный элемент + x = 10; // не исходный элемент + function boo() {} // не исходный элемент +} +function foo() { // исходный элемент + var y = 20; // исходный элемент + function bar() {} // исходный элемент + while (y == 10) { // исходный элемент + function blah() {} // не исходный элемент + y++; // не исходный элемент + } +} +</pre> + +<h3 id="Примеры">Примеры</h3> + +<pre class="brush: js">// объявление функции +function foo() {} + +// функция-выражение +(function bar() {}) + +// функция-выражение +x = function hello() {} + + +if (x) { + // функция-выражение + function world() {} +} + + +// объявление функции +function a() { + // обявление функции + function b() {} + if (0) { + // функция-выражение + function c() {} + } +} +</pre> + +<h2 id="Conditionally_defining_a_function" name="Conditionally_defining_a_function">Определение функции в зависимости от условия</h2> + +<p>Функции могут быть определены в зависимости от условий с помощью инструкции <code>function (разрешённое расширение стандарта</code> <a href="http://www.ecma-international.org/publications/standards/Ecma-262.htm">ECMA-262 Edition 3</a>) или конструктора <code>Function</code>. Обратите внимание, что подобные инструкции <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=609832">запрещены в ES5 strict</a>. Кроме того, эта возможность по-разному ведёт себя в разных браузерах, поэтому не стоит на неё рассчитывать.</p> + +<p>В коде ниже функция <code>zero</code> никогда не будет определена и не может быть вызвана, потому что '<code>if (0)</code>' всегда расценивается как <code>false</code>:</p> + +<pre class="brush: js">if (0) { + function zero() { + document.writeln("This is zero."); + } +} +</pre> + +<p>Если изменить условие на '<code>if (1)</code>', функция <code>zero</code> будет определена.</p> + +<p>Заметьте, что хотя это выглядит как объявление функции, на самом деле, это функция-выражение (или инструкция), так как она вложена внутрь другой инструкции. Изучите разницу между объявлением функции и функцией-выражением.</p> + +<p>Некоторые JavaScript-движки (но не <a href="/en-US/docs/SpiderMonkey">SpiderMonkey</a>), неверно считают любую функцию-выражение с именем за объявление функции. Это приводит к тому, что функция <code>zero</code> будет определена, даже если условие всегда <code>false</code>. Более безопасный способ определить функцию по условию - это сделать её анонимной и приравнять к переменной:</p> + +<pre class="brush: js">if (0) { + var zero = function() { + document.writeln("This is zero."); + } +} +</pre> + +<h2 id="Examples" name="Examples">Примеры</h2> + +<h3 id="Example:_Returning_a_formatted_number" name="Example:_Returning_a_formatted_number">Пример: возврат отформатированного числа</h3> + +<p>Эта функция возвращает строку, содержащую число с заданным количеством нулей перед ним:</p> + +<pre class="brush: js">function padZeros(num, totalLen) { + var numStr = num.toString(); // Инициализировать возвращаемое значение в виде строки + var numZeros = totalLen - numStr.length; // Посчитать число нулей в начале + for (var i = 1; i <= numZeros; i++) { + numStr = "0" + numStr; + } + return numStr; +} +</pre> + +<p>Вызовем <code>padZeros</code>:</p> + +<pre class="brush: js">var result; +result = padZeros(42,4); // возвращает "0042" +result = padZeros(42,2); // возвращает "42" +result = padZeros(5,4); // возвращает "0005" +</pre> + +<h3 id="Example:_Determining_whether_a_function_exists" name="Example:_Determining_whether_a_function_exists">Пример: существует ли функция</h3> + +<p>Можно определить, существует ли функция с помощью оператора <code>typeof</code>. В следующем примере проверяется, есть ли у объекта <code>window</code> функция <code>noFunc</code>. Если есть, то она вызывается; если нет, выполняется какое-то другое действие.</p> + +<pre class="brush: js"> if ('function' == typeof window.noFunc) { + // вызывать noFunc() + } else { + // сделать что-то другое + } +</pre> + +<p>Заметьте, что в проверке условия используется ссылка на <code>noFunc</code> — после имени функции нет скобок, поэтому сама функция не вызывается.</p> + +<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>Изначальное определение. Релизовано в JavaScript 1.0</td> + </tr> + <tr> + <td>{{SpecName('ES5.1', '#sec-13', 'Function Definition')}}</td> + <td>{{Spec2('ES5.1')}}</td> + <td> </td> + </tr> + <tr> + <td>{{SpecName('ES6', '#sec-function-definitions', 'Function definitions')}}</td> + <td>{{Spec2('ES6')}}</td> + <td>Новое: стрелочные функции, генераторы, параметры по умолчанию, оставшиеся параметры</td> + </tr> + </tbody> +</table> + +<h2 id="Поддержка_браузерами">Поддержка браузерами</h2> + +<p>{{ CompatibilityTable() }}</p> + +<div id="compat-desktop"> +<table class="compat-table"> + <tbody> + <tr> + <th>Feature</th> + <th>Chrome</th> + <th>Firefox (Gecko)</th> + <th>Internet Explorer</th> + <th>Opera</th> + <th>Safari</th> + </tr> + <tr> + <td>Начальная поддержка</td> + <td>{{ CompatVersionUnknown() }}</td> + <td>{{ CompatVersionUnknown() }}</td> + <td>{{ CompatVersionUnknown() }}</td> + <td>{{ CompatVersionUnknown() }}</td> + <td>{{ CompatVersionUnknown() }}</td> + </tr> + </tbody> +</table> +</div> + +<div id="compat-mobile"> +<table class="compat-table"> + <tbody> + <tr> + <th>Feature</th> + <th>Android</th> + <th>Chrome for Android</th> + <th>Firefox Mobile (Gecko)</th> + <th>IE Mobile</th> + <th>Opera Mobile</th> + <th>Safari Mobile</th> + </tr> + <tr> + <td>Начальная поддержка</td> + <td>{{ CompatVersionUnknown() }}</td> + <td>{{ CompatVersionUnknown() }}</td> + <td>{{ CompatVersionUnknown() }}</td> + <td>{{ CompatVersionUnknown() }}</td> + <td>{{ CompatVersionUnknown() }}</td> + <td>{{ CompatVersionUnknown() }}</td> + </tr> + </tbody> +</table> +</div> + +<h2 id="See_also" name="See_also">См. также</h2> + +<ul> + <li><a href="https://developer.mozilla.org/ru/docs/Web/JavaScript/Reference/Global_Objects/Function"><code>Function</code></a></li> + <li><a href="https://developer.mozilla.org/ru/docs/Web/JavaScript/Reference/Statements/function">Инструкция<code> function</code></a></li> + <li><a href="https://developer.mozilla.org/ru/docs/Web/JavaScript/Reference/Operators/function">Оператор<code> function</code></a></li> +</ul> diff --git a/files/ru/web/javascript/reference/functions/rest_parameters/index.html b/files/ru/web/javascript/reference/functions/rest_parameters/index.html new file mode 100644 index 0000000000..14d9c1e334 --- /dev/null +++ b/files/ru/web/javascript/reference/functions/rest_parameters/index.html @@ -0,0 +1,209 @@ +--- +title: Оставшиеся параметры (rest parameters) +slug: Web/JavaScript/Reference/Functions/Rest_parameters +tags: + - JavaScript + - Оставшиеся параметры + - Функции +translation_of: Web/JavaScript/Reference/Functions/rest_parameters +--- +<div>{{jsSidebar("Functions")}} </div> + +<p>Синтаксис <strong>оставшихся параметров</strong> функции позволяет представлять неограниченное множество аргументов в виде массива.</p> + +<p>{{EmbedInteractiveExample("pages/js/functions-restparameters.html")}}</p> + +<h2 id="Syntax" name="Syntax">Синтаксис</h2> + +<pre class="brush: js notranslate">function(a, b, ...theArgs) { + // ... +} +</pre> + +<h2 id="Описание">Описание</h2> + +<p>Если последний именованный аргумент функции имеет префикс <code>...</code>, он автоматически становится массивом с элементами от <code>0</code> до <code>theArgs.length-1</code> в соответствии с актуальным количеством аргументов, переданных в функцию.</p> + +<pre class="brush: js notranslate">function myFun(a, b, ...manyMoreArgs) { + console.log("a", a); + console.log("b", b); + console.log("manyMoreArgs", manyMoreArgs); +} + +myFun("один", "два", "три", "четыре", "пять", "шесть"); + +// Console Output: +// a, один +// b, два +// manyMoreArgs, [три, четыре, пять, шесть] +</pre> + +<h3 id="Отличия_оставшихся_параметров_от_объекта_arguments">Отличия оставшихся параметров от объекта <code>arguments</code></h3> + +<p>Существует три основных отличия оставшихся параметров от объекта <a href="/ru/docs/Web/JavaScript/Reference/Functions/arguments" title="arguments"><code>arguments</code></a>:</p> + +<ul> + <li>оставшиеся параметры включают только те, которым не задано отдельное имя, в то время как объект <code>arguments</code> содержит все аргументы, передаваемые в функцию;</li> + <li>объект <code>arguments</code> не является массивом, в то время как оставшиеся параметры являются экземпляром <a href="/ru/docs/Web/JavaScript/Reference/Global_Objects/Array" title="Array"><code>Array</code></a> и методы <a href="/ru/docs/Web/JavaScript/Reference/Global_Objects/Array/sort" title="Array sort method"><code>sort</code></a>, <a href="/ru/docs/Web/JavaScript/Reference/Global_Objects/Array/map" title="Array map method"><code>map</code></a>, <a href="/ru/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach" title="Array forEach method"><code>forEach</code></a> или <a href="/ru/docs/Web/JavaScript/Reference/Global_Objects/Array/pop" title="Array pop method"><code>pop</code></a> могут непосредственно у них использоваться;</li> + <li>объект <code>arguments</code> имеет дополнительную функциональность, специфичную только для него (например, свойство <code>callee</code>).</li> +</ul> + +<h3 id="Из_аргументов_в_массив">Из аргументов в массив</h3> + +<p>Оставшиеся параметры были введены для уменьшения количества шаблонного кода:</p> + +<pre class="brush: js notranslate">// До появления оставшихся параметров "arguments" конвертировали в обычный массив используя: + +function f(a, b) { + + var normalArray = Array.prototype.slice.call(arguments); + // -- или -- + var normalArray = [].slice.call(arguments); + // -- или -- + var normalArray = Array.from(arguments); + + var first = normalArray.shift(); // OK, даёт первый аргумент + var first = arguments.shift(); // ERROR (arguments не является обычным массивом) + +} + +// Теперь мы можем легко получить оставшиеся параметры как обычный массив + +function f(...args) { + var normalArray = args; + var first = normalArray.shift(); // OK, даёт первый аргумент +}</pre> + +<h3 id="Деструктуризация_оставшихся_параметров">Деструктуризация оставшихся параметров</h3> + +<p>Оставшиеся парамерты могут быть деструктуризованы (только массивы). Это означает, что их данные могут быть заданы как отдельные значения. Смотрите <a href="/ru/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment">Деструктурирующее присваивание</a>.</p> + +<pre class="notranslate"><code>function f(...[a, b, c]) { + return a + b + c; +} + +f(1) // NaN (b и c равны undefined) +f(1, 2, 3) // 6 +f(1, 2, 3, 4) // 6 (четвёртый параметр не деструктурирован)</code></pre> + +<h2 id="Example" name="Example">Примеры</h2> + +<p>В этом примере первый аргумент задан как <code>"a"</code>, второй как <code>"b"</code>, так что эти аргументы используются как обычно. Однако третий аргумент <code>"manyMoreArgs"</code> будет массивом, который содержит 3-й, 4-й, 5-й, 6-й ... n-й аргументы, которые передаст пользователь.</p> + +<pre class="brush: js notranslate">function myFun(a, b, ...manyMoreArgs) { + console.log("a", a); + console.log("b", b); + console.log("manyMoreArgs", manyMoreArgs); +} + +myFun("один", "два", "три", "четыре", "пять", "шесть"); + +// a, один +// b, два +// manyMoreArgs, [три, четыре, пять, шесть]</pre> + +<p>Ниже... даже если передано одно значение последним аргументом, оно всё равно помещается в массив.</p> + +<pre class="brush: js notranslate">// использование той же функции, что и в примере выше + +myFun("один", "два", "три"); + +// a, один +// b, два +// manyMoreArgs, [три]</pre> + +<p>Ниже... третий аргумент не был передан, но "manyMoreArgs" всё ещё массив (хотя и пустой).</p> + +<pre class="brush: js notranslate">// использование той же функции, что и в примере выше + +myFun("один", "два"); + +// a, один +// b, два +// manyMoreArgs, []</pre> + +<p>Поскольку <code>theArgs</code> является массивом, количество элементов в нём определяется свойством <code>length</code>:</p> + +<pre class="brush: js notranslate">function fun1(...theArgs) { + console.log(theArgs.length); +} + +fun1(); // 0 +fun1(5); // 1 +fun1(5, 6, 7); // 3</pre> + +<p>В следующем примере, оставшиеся параметры используются для сбора всех аргументов после первого в массив. Каждый из них умножается на первый параметр и возвращается массив:</p> + +<pre class="brush: js notranslate"><code>function multiply(multiplier, ...theArgs) { + return theArgs.map(function(element) { + return multiplier * element; + }); +} + +var arr = multiply(2, 1, 2, 3); +console.log(arr); // [2, 4, 6]</code></pre> + +<p>Методы <code>Array</code> могут быть использованы на оставшихся параметрах, но не на объекте <code>arguments</code>: </p> + +<pre class="brush: js notranslate">function sortRestArgs(...theArgs) { + var sortedArgs = theArgs.sort(); + return sortedArgs; +} + +console.log(sortRestArgs(5, 3, 7, 1)); // 1, 3, 5, 7 + +function sortArguments() { + var sortedArgs = arguments.sort(); + return sortedArgs; // это никогда не выполнится +} + + +console.log(sortArguments(5, 3, 7, 1)); // TypeError (arguments.sort is not a function)</pre> + +<p>Чтобы использовать методы <code>Array</code> на объекте <code>arguments</code>, нужно преобразовать его в настоящий массив.</p> + +<pre class="brush: js notranslate"><code>function sortArguments() { + var args = Array.from(arguments); + var sortedArgs = args.sort(); + return sortedArgs; +} +console.log(sortArguments(5, 3, 7, 1)); // 1, 3, 5, 7</code></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>{{SpecName('ES6', '#sec-function-definitions', 'Определение функций')}}</td> + <td>{{Spec2('ES6')}}</td> + <td>Изначальное определение.</td> + </tr> + <tr> + <td>{{SpecName('ESDraft', '#sec-function-definitions', 'Function Definitions')}}</td> + <td>{{Spec2('ESDraft')}}</td> + <td></td> + </tr> + </tbody> +</table> + +<h2 id="Совместимость_с_браузерами">Совместимость с браузерами</h2> + +<div>{{Compat("javascript.functions.rest_parameters")}}</div> + +<div id="compat-mobile"></div> + +<h2 id="See_also" name="See_also">Смотрите также</h2> + +<ul> + <li><a href="/ru/docs/Web/JavaScript/Reference/Functions/arguments" title="arguments">Объект arguments</a></li> + <li><a href="/ru/docs/Web/JavaScript/Reference/Global_Objects/Array" title="Array">Array</a></li> + <li><a href="/ru/docs/Web/JavaScript/Reference/Functions" title="Functions and function scope">Функции</a></li> + <li><a href="/ru/docs/Web/JavaScript/Reference/Operators/Spread_operator" title="spread operator">Оператор распространения</a></li> + <li><a class="external" href="http://wiki.ecmascript.org/doku.php?id=harmony:rest_parameters">Оригинальное предложение на ecmascript.org</a></li> + <li><a class="external" href="http://javascriptweblog.wordpress.com/2011/01/18/javascripts-arguments-object-and-beyond/">JavaScript arguments object and beyond</a></li> +</ul> diff --git a/files/ru/web/javascript/reference/functions/set/index.html b/files/ru/web/javascript/reference/functions/set/index.html new file mode 100644 index 0000000000..8d51101997 --- /dev/null +++ b/files/ru/web/javascript/reference/functions/set/index.html @@ -0,0 +1,134 @@ +--- +title: setter +slug: Web/JavaScript/Reference/Functions/set +translation_of: Web/JavaScript/Reference/Functions/set +--- +<div>{{jsSidebar("Functions")}}</div> + +<p>Оператор <strong><code>set</code></strong> связывает свойство объекта с функцией, которая будет вызвана при попытке установить это свойство.</p> + +<h2 id="Синтаксис">Синтаксис</h2> + +<pre class="syntaxbox">{set <em>prop</em>(<em>val</em>) { . . . }} +{set [expression](<em>val</em>) { . . . }}</pre> + +<h3 id="Параметры">Параметры</h3> + +<dl> + <dt><code>prop</code></dt> + <dd>Имя свойства для привязки к заданной функции.</dd> +</dl> + +<dl> + <dt><code>val</code></dt> + <dd>Псевдоним переменной, которая хранит значение, неудавшегося определения <code>prop.</code></dd> + <dt>expression</dt> + <dd>Начиная с ECMAScript 6, вы также можете использовать выражения для вычисляемого имя свойства для привязки к данной функции.</dd> +</dl> + +<h2 id="Описание">Описание</h2> + +<p>В JavaScript, сеттер можно использовать для выполнения функции, когда будет попытка изменения указанного свойства. Сеттеры используются чаще всего в сочетании с геттерами для создания одного из видов псевдо-свойства. Невозможно одновременно иметь сеттер для свойства, которое содержит фактическое значение.</p> + +<p>Обратите внимание на следующие моменты при работе с синтаксисом <code>set</code>:</p> + +<div> +<ul> + <li>Он может иметь идентификатор, который является либо числом, либо строкой;</li> + <li>Он должен иметь ровно один параметр (смотрите <a class="external" href="http://whereswalden.com/2010/08/22/incompatible-es5-change-literal-getter-and-setter-functions-must-now-have-exactly-zero-or-one-arguments/" rel="external nofollow">Incompatible <abbr title="ECMAScript 5th edition">ES5</abbr> change: literal getter and setter functions must now have exactly zero or one arguments</a> для более подробной информации);</li> + <li>Он не должен объявляться в литерале объекта, с другим набором или вводом данных для того же самого свойства.<br> + ( <code>{ set x(v) { }, set x(v) { } }</code> и <code>{ x: ..., set x(v) { } }</code> запрещены)</li> +</ul> +</div> + +<p>Сеттер может быть удален оператором <a href="/en-US/docs/Web/JavaScript/Reference/Operators/delete" title="en-US/docs/JavaScript/Reference/Operators/Special/delete"><code>delete</code></a>.</p> + +<h2 id="Примеры">Примеры</h2> + +<h3 id="Определение_сеттера_при_инициализации_новых_объектов">Определение сеттера при инициализации новых объектов</h3> + +<p>Это позволит определить псевдо-параметр <code>current</code> объекта <code>o</code>, который задает значение, обновляющее значение <code>log</code>:</p> + +<pre class="brush: js">var o = { + set current (str) { + this.log[this.log.length] = str; + }, + log: [] +} +</pre> + +<p><code>обратите внимание, что current</code> не определен и любые попытки доступа к нему вернут <code>undefined</code>.</p> + +<h3 id="Удаление_сеттера_оператором_delete">Удаление сеттера оператором <code>delete</code></h3> + +<p>Если вы хотите удалить сеттер, вы можете просто его <code><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/delete">удалить</a></code>:</p> + +<pre class="brush: js">delete o.current; +</pre> + +<h3 id="Определение_сеттера_для_существующих_объектов_используя_defineProperty">Определение сеттера для существующих объектов используя <code>defineProperty</code></h3> + +<p>Чтобы добавить сеттер на существующий объект в любое время, используйте {{jsxref("Object.defineProperty()")}}.</p> + +<pre class="brush: js">var o = { a:0 }; + +Object.defineProperty(o, "b", { set: function (x) { this.a = x / 2; } }); + +o.b = 10; // Запускает сеттер, который присваивает 10 / 2 (5) свойству 'a' +console.log(o.a) // 5</pre> + +<h3 id="Использование_вычисляемого_имени_свойства">Использование вычисляемого имени свойства </h3> + +<pre class="brush: js">var expr = "foo"; + +var obj = { + baz: "bar", + set [expr](v) { this.baz = v; } +}; + +console.log(obj.baz); // "bar" +obj.foo = "baz"; // запускает сеттер +console.log(obj.baz); // "baz" +</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>{{SpecName('ES5.1', '#sec-11.1.5', 'Object Initializer')}}</td> + <td>{{Spec2('ES5.1')}}</td> + <td>Начальное определение.</td> + </tr> + <tr> + <td>{{SpecName('ES6', '#sec-method-definitions', 'Method definitions')}}</td> + <td>{{Spec2('ES6')}}</td> + <td>Добавлены вычесляемые имена свойств</td> + </tr> + <tr> + <td>{{SpecName('ESDraft', '#sec-method-definitions', 'Method definitions')}}</td> + <td>{{Spec2('ESDraft')}}</td> + <td> </td> + </tr> + </tbody> +</table> + +<p><font face="x-locale-heading-primary, zillaslab, Palatino, Palatino Linotype, x-locale-heading-secondary, serif"><span style="font-size: 40px;"><strong>Совместимость с браузерами</strong></span></font></p> + +<p>{{Compat("javascript.functions.set")}}</p> + +<h2 id="Смотрите_также">Смотрите также</h2> + +<ul> + <li><a href="/en-US/docs/Web/JavaScript/Reference/Functions/get">getter</a></li> + <li>{{jsxref("Operators/delete", "delete")}}</li> + <li>{{jsxref("Object.defineProperty()")}}</li> + <li>{{jsxref("Object.defineGetter", "__defineGetter__")}}</li> + <li>{{jsxref("Object.defineSetter", "__defineSetter__")}}</li> + <li><a href="/en-US/docs/Web/JavaScript/Guide/Working_with_Objects#Defining_getters_and_setters">Defining Getters and Setters</a> в реководстве по JavaScript</li> +</ul> diff --git a/files/ru/web/javascript/reference/functions/определиние_методов/index.html b/files/ru/web/javascript/reference/functions/определиние_методов/index.html new file mode 100644 index 0000000000..2f50dfe53f --- /dev/null +++ b/files/ru/web/javascript/reference/functions/определиние_методов/index.html @@ -0,0 +1,191 @@ +--- +title: Определение методов +slug: Web/JavaScript/Reference/Functions/Определиние_методов +translation_of: Web/JavaScript/Reference/Functions/Method_definitions +--- +<div>{{JsSidebar("Functions")}}</div> + +<p>Начиная с ECMAScript 6, существует короткий синтаксис для определения методов в инициализаторе объекта. По сути, это сокращение для функции, которая назначена имени метода.</p> + +<h2 id="Синтаксис">Синтаксис</h2> + +<pre class="syntaxbox">var obj = { + <var>property</var>([<var>parameters</var>]) {}, + get <var>property</var>() {}, + set <var>property</var>(<var>value</var>) {}, + * <var>generator</var>() {} +}; +</pre> + +<h2 id="Описание">Описание</h2> + +<p>Короткий синтаксис похожий на синтаксис <a href="/en-US/docs/Web/JavaScript/Reference/Functions/get">getter</a>'ов и <a href="/en-US/docs/Web/JavaScript/Reference/Functions/set">setter</a>'ов представленых в ECMAScript 5.</p> + +<p>Следующий код:</p> + +<pre class="brush: js">var obj = { + foo: function() {}, + bar: function() {} +};</pre> + +<p>Вы теперь можете сократить до:</p> + +<pre class="brush: js">var obj = { + foo() {}, + bar() {} +};</pre> + +<h3 id="Сокращение_методов-генераторов">Сокращение методов-генераторов</h3> + +<p><a href="/en-US/docs/Web/JavaScript/Reference/Statements/function*">Методы-генераторы</a> также могут быть определены используя короткий синтаксис. Обратите внимание, что звездочка (*) в коротком синтаксисе должна быть перед именем свойства генератора. То есть, <code>* g(){}</code> будет работать, а <code>g *(){}</code> не будет.</p> + +<pre class="brush: js;highlight[12]">// Используя свойство с именем (pre-ES6) +var obj2 = { + g: function*() { + var index = 0; + while(true) + yield index++; + } +}; + +// Тот же объект используя короткий синтаксис +var obj2 = { + * g() { + var index = 0; + while(true) + yield index++; + } +}; + +var it = obj2.g(); +console.log(it.next().value); // 0 +console.log(it.next().value); // 1</pre> + +<h3 id="Определения_методов_(ES6)_не_могут_быть_конструкторами">Определения методов (ES6) не могут быть конструкторами</h3> + +<p>Все определения методов кроме методов-генераторов не могут быть конструкторами и будут выбрасывать {{jsxref("TypeError")}} если вы попытаетесь создать их экземпляр.</p> + +<pre class="brush: js">var obj = { + method() {}, +}; +new obj.method; // TypeError: obj.method is not a constructor + +var obj = { + * g() {} +}; +new obj.g; // Генератор +</pre> + +<h2 id="Примеры">Примеры</h2> + +<h3 id="Простой_тестовый_пример">Простой тестовый пример</h3> + +<pre class="brush: js;highlight[3]">var obj = { + a : "foo", + b(){ return this.a; } +}; +console.log(obj.b()); // "foo" +</pre> + +<h3 id="Вычисляемые_имена_свойств">Вычисляемые имена свойств</h3> + +<p>Короткий синтаксис также поддерживает вычисляемые имена свойств.</p> + +<pre class="brush: js;highlight[4]">var bar = { + foo0 : function (){return 0;}, + foo1(){return 1;}, + ["foo" + 2](){return 2;}, +}; + +console.log(bar.foo0()); // 0 +console.log(bar.foo1()); // 1 +console.log(bar.foo2()); // 2</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>{{SpecName('ES6', '#sec-method-definitions', 'Method definitions')}}</td> + <td>{{Spec2('ES6')}}</td> + <td>Изначальное определение.</td> + </tr> + </tbody> +</table> + +<h2 id="Совместимость_с_браузерами">Совместимость с браузерами</h2> + +<div>{{CompatibilityTable}}</div> + +<div id="compat-desktop"> +<table class="compat-table"> + <tbody> + <tr> + <th>Feature</th> + <th>Chrome</th> + <th>Firefox (Gecko)</th> + <th>Internet Explorer</th> + <th>Opera</th> + <th>Safari</th> + </tr> + <tr> + <td>Method definition shorthand</td> + <td>{{CompatChrome("39")}}</td> + <td>{{CompatGeckoDesktop("34")}}</td> + <td>{{CompatNo}}</td> + <td>{{CompatOpera("26")}}</td> + <td>{{CompatNo}}</td> + </tr> + </tbody> +</table> +</div> + +<div id="compat-mobile"> +<table class="compat-table"> + <tbody> + <tr> + <th>Feature</th> + <th>Android</th> + <th>Chrome for Android</th> + <th>Firefox Mobile (Gecko)</th> + <th>IE Mobile</th> + <th>Opera Mobile</th> + <th>Safari Mobile</th> + </tr> + <tr> + <td>Method definition shorthand</td> + <td>{{CompatNo}}</td> + <td>{{CompatNo}}</td> + <td>{{CompatGeckoMobile("34")}}</td> + <td>{{CompatNo}}</td> + <td>{{CompatNo}}</td> + <td>{{CompatNo}}</td> + </tr> + </tbody> +</table> +</div> + +<h2 id="sect1"> </h2> + +<h2 id="SpiderMonkey-specific_notes">SpiderMonkey-specific notes</h2> + +<ul> + <li>Prior to SpiderMonkey 38 {{geckoRelease(38)}}, "<code>get</code>" and "<code>set</code>" were invalid names for generator methods. This has been fixed in {{bug(1073809)}}.</li> + <li>Prior to SpiderMonkey 41 {{geckoRelease(41)}}, curly braces were not required in method definitions. They are required from now on to conform to the ES6 specification and will throw a {{jsxref("SyntaxError")}} in this and later versions ({{bug(1150855)}}). + <pre class="brush: js example-bad">var o = {x() 12}; // SyntaxError</pre> + </li> + <li>The restriction that only generator methods are constructors has been implemented in SpiderMonkey 41 {{geckoRelease(41)}}. See also {{bug(1059908)}} and {{bug(1166950)}}.</li> +</ul> + +<h2 id="Смотрите_также">Смотрите также</h2> + +<ul> + <li><code><a href="/en-US/docs/Web/JavaScript/Reference/Functions/get">get</a></code></li> + <li><code><a href="/en-US/docs/Web/JavaScript/Reference/Functions/set">set</a></code></li> + <li><a href="/en-US/docs/Web/JavaScript/Reference/Lexical_grammar">Lexical grammar</a></li> +</ul> |