aboutsummaryrefslogtreecommitdiff
path: root/files/ru/web/javascript/reference/functions/arrow_functions/index.html
diff options
context:
space:
mode:
authorPeter Bengtsson <mail@peterbe.com>2020-12-08 14:42:52 -0500
committerPeter Bengtsson <mail@peterbe.com>2020-12-08 14:42:52 -0500
commit074785cea106179cb3305637055ab0a009ca74f2 (patch)
treee6ae371cccd642aa2b67f39752a2cdf1fd4eb040 /files/ru/web/javascript/reference/functions/arrow_functions/index.html
parentda78a9e329e272dedb2400b79a3bdeebff387d47 (diff)
downloadtranslated-content-074785cea106179cb3305637055ab0a009ca74f2.tar.gz
translated-content-074785cea106179cb3305637055ab0a009ca74f2.tar.bz2
translated-content-074785cea106179cb3305637055ab0a009ca74f2.zip
initial commit
Diffstat (limited to 'files/ru/web/javascript/reference/functions/arrow_functions/index.html')
-rw-r--r--files/ru/web/javascript/reference/functions/arrow_functions/index.html378
1 files changed, 378 insertions, 0 deletions
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) =&gt; { statements }
+(param1, param2, …, paramN) =&gt; expression
+// эквивалентно: (param1, param2, …, paramN) =&gt; { return expression; }
+
+// Круглые скобки не обязательны для единственного параметра:
+(singleParam) =&gt; { statements }
+singleParam =&gt; { statements }
+
+// Функция без параметров нуждается в круглых скобках:
+() =&gt; { statements }
+() =&gt; expression
+// Эквивалентно: () =&gt; { return expression; }
+</pre>
+
+<h3 id="Расширенный_синтаксис">Расширенный синтаксис</h3>
+
+<pre class="brush: js">// Когда возвращаете литеральное выражение объекта, заключите тело в скобки
+params =&gt; ({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) =&gt; { statements }
+(param1 = defaultValue1, param2, …, paramN = defaultValueN) =&gt; { 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}) =&gt; 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) =&gt; {
+ return element.length;
+}); // [8, 6, 7, 9]
+
+// Если единственным оператором в выражении стрелочной функции является return,
+// можно удалить return и окружающие фигурные скобки
+
+elements.map(element =&gt; element.length); // [8, 6, 7, 9]
+
+// В данном случае, поскольку нам нужно только свойство length, мы можем использовать деструктуризированный параметр:
+// Обратите внимание, что строка `"length"` соответствует свойству, которое мы хотим получить,
+// в то время как `lengthFooBArX` это просто имя переменной, которую можно назвать как вы хотите
+elements.map(({ "length": lengthFooBArX }) =&gt; lengthFooBArX); // [8, 6, 7, 9]
+
+// Это задание деструктуризированного параметра может быть записано, как показано ниже. Тем не менее, обратите внимание,
+// что нет строки `"length"`, чтобы выбрать, какое свойство мы хотим получить. Вместо этого в качестве свойства,
+// которое мы хотим извлечь из объекта, используется само литеральное имя переменной `length`
+elements.map(({ length }) =&gt; 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(() =&gt; {
+ 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 = () =&gt; { '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 =&gt; v + this.base;
+ return f(a);
+ },
+
+ addThruCall: function(a) {
+ var f = v =&gt; 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 = () =&gt; arguments;
+
+arr(); // 42
+
+function foo() {
+ var f = (i) =&gt; 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) =&gt; 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: () =&gt; 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: () =&gt; {
+ 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 (() =&gt; {})
+// будет выброшено исключени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 =&gt; x * x; // краткий синтаксис,
+  // неявно возвращает результат
+var func = (x, y) =&gt; { return x + y; }; // блочный синтаксис,
+  // явно возвращает результат</pre>
+
+<h2 id="Возвращаемые_объектные_строки_литералы">Возвращаемые объектные строки (литералы)</h2>
+
+<p>Помните о том, что возвращаемые <a href="/ru/docs/Web/JavaScript/Guide/Grammar_and_types#Литерал_объекта/">объектные строки</a> используют сокращённый синтаксис: <code>params =&gt; {object:literal}</code> будет работать не так, как ожидается.</p>
+
+<pre class="brush: js">var func = () =&gt; { foo: 1 };
+// Вызов func() возвращает undefined!
+
+var func = () =&gt; { foo: function() {} };
+// SyntaxError: function statement requires a name</pre>
+
+<p>Это происходит потому что код в скобках ({}) распознаётся как цепочка выражений (т.е. <code>foo</code> трактуется как наименование, а не как ключ в объектной строке).</p>
+
+<p>Не забывайте оборачивать скобками объектные строки.</p>
+
+<pre class="brush: js">var func = () =&gt; ({ foo: 1 });</pre>
+
+<h2 id="Разрывы_строк">Разрывы строк</h2>
+
+<p>Стрелочная функция не может содержать разрывы строк между параметрами и стрелкой.</p>
+
+<pre class="brush: js line-numbers language-js">var func = ()
+ =&gt; 1;
+// SyntaxError: expected expression, got '=&gt;'
+</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 || () =&gt; {};
+// SyntaxError: invalid arrow-function arguments
+
+callback = callback || (() =&gt; {}); // ok
+</pre>
+
+<h2 id="Больше_примеров">Больше примеров</h2>
+
+<pre class="brush: js">// Пустая стрелочная функция возвращает undefined
+let empty = () =&gt; {};
+
+(() =&gt; '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 =&gt; a &gt; 15 ? 15 : a;
+simple(16); // 15
+simple(10); // 10
+
+let max = (a, b) =&gt; a &gt; b ? a : b;
+
+// Удобные операции над массивами: filter, map, ...
+
+var arr = [5, 6, 13, 0, 1, 18, 23];
+
+var sum = arr.reduce((a, b) =&gt; a + b);
+// 66
+
+var even = arr.filter(v =&gt; v % 2 == 0);
+// [6, 0, 18]
+
+var double = arr.map(v =&gt; v * 2);
+// [10, 12, 26, 0, 2, 36, 46]
+
+// Более короткие цепочки promise-ов
+promise.then(a =&gt; {
+ // ...
+}).then(b =&gt; {
+ // ...
+});
+
+// Стрелочные функции без параметров, которые визуально легче разбирать
+setTimeout( () =&gt; {
+ console.log('Я буду раньше');
+ setTimeout( () =&gt; {
+ // 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 =&gt; {}</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>