From daa1a2aff136fa9da1fcc97d7da97a2036fabc77 Mon Sep 17 00:00:00 2001 From: Florian Merz Date: Thu, 11 Feb 2021 14:51:47 +0100 Subject: unslug uk: move --- .../reference/functions/arrow_functions/index.html | 362 +++++++++++++++++++++ .../reference/functions/rest_parameters/index.html | 211 ++++++++++++ .../index.html" | 211 ------------ .../index.html" | 362 --------------------- 4 files changed, 573 insertions(+), 573 deletions(-) create mode 100644 files/uk/web/javascript/reference/functions/arrow_functions/index.html create mode 100644 files/uk/web/javascript/reference/functions/rest_parameters/index.html delete mode 100644 "files/uk/web/javascript/reference/functions/\321\200\320\265\321\210\321\202\320\260_\320\277\320\260\321\200\320\260\320\274\320\265\321\202\321\200\321\226\320\262/index.html" delete mode 100644 "files/uk/web/javascript/reference/functions/\321\201\321\202\321\200\321\226\320\273\320\272\320\276\320\262\321\226_\321\204\321\203\320\275\320\272\321\206\321\226\321\227/index.html" (limited to 'files/uk/web/javascript/reference/functions') diff --git a/files/uk/web/javascript/reference/functions/arrow_functions/index.html b/files/uk/web/javascript/reference/functions/arrow_functions/index.html new file mode 100644 index 0000000000..f1638d8d84 --- /dev/null +++ b/files/uk/web/javascript/reference/functions/arrow_functions/index.html @@ -0,0 +1,362 @@ +--- +title: Стрілкові функції +slug: Web/JavaScript/Reference/Functions/Стрілкові_функції +translation_of: Web/JavaScript/Reference/Functions/Arrow_functions +--- +
{{jsSidebar("Functions")}}
+ +

Вирази стрілкових функцій мають більш короткий синтаксис, аніж функціональні вирази і не мають свого власного this, arguments, super, і new.target. Вони не можуть бути використані як конструктор і завжди анонімні.

+ +

Синтаксис

+ +

Basic Syntax

+ +
(параметр1,параметр2, …, параметрN) => { оператори }
+(параметр1, параметр2, …, параметрN) => вираз
+// еквівалентно до запису: (параметр1,параметр2, …, параметрN) => { return вираз; }
+
+// Якщо у функції тільки один параметр, то дужки не обов'язкові:
+(параметр) => { оператори }
+параметр => { оператори }
+параметр => вираз
+
+
+// Список параметрів для функції без параметрів повинен бути записаний у парі фігурних дужок.
+() => { оператори }
+
+ +

Advanced Syntax

+ +
// Візьміть тіло функції у дужки, якщо вона повертає об'єкт
+params => ({foo: bar})
+
+// Залишкові параметри та параметри за замовчуванням підтримуються як і в звичайних функціях
+(параметр1, параметр2, ...залишкові параметри) => { оператори }
+(параметр1 = значення_за_замовчуванням, параметр2, …, параметрN = значення_за_замовчуваннямN) => { оператори }
+
+// Деструктиризація в списку параметрів також підтримується:
+let f = ([a, b] = [1, 2], {x: c} = {x: a + b}) => a + b + c;
+f();
+// 6
+
+ +

Опис

+ +

Див. також "ES6 In Depth: Arrow functions" on hacks.mozilla.org.

+ +

Появу стрілкових функцій зумовили два фактори: можливість більш короткого запису і випадки, коли сутність this не обов'язкова.

+ +

Коротший запис

+ +
var materials = [
+  'Hydrogen',
+  'Helium',
+  'Lithium',
+  'Beryllium'
+];
+
+materials.map(function(material) {
+  return material.length;
+}); // [8, 6, 7, 9]
+
+materials.map((material) => {
+  return material.length;
+}); // [8, 6, 7, 9]
+
+materials.map(material => material.length); // [8, 6, 7, 9]
+
+ +

Спільний this

+ +

До появи стрілкових функцій кожна нова функція мала власне значення this :

+ + + +

Це все було далеким від ідеалів об'єктно-орієнтованого програмування.

+ +
function Person() {
+  // The Person() constructor defines `this` as an instance of itself.
+  this.age = 0;
+
+  setInterval(function growUp() {
+    // In non-strict mode, the growUp() function defines `this`
+    // as the global object, which is different from the `this`
+    // defined by the Person() constructor.
+    this.age++;
+  }, 1000);
+}
+
+var p = new Person();
+ +

В ECMAScript 3/5 ця проблема вирішувалась шляхом присвоєння значення this змінній, оголошеній всередині функції.

+ +
function Person() {
+  var that = this;
+  that.age = 0;
+
+  setInterval(function growUp() {
+    // The callback refers to the `that` variable of which
+    // the value is the expected object.
+    that.age++;
+  }, 1000);
+}
+ +

Або можна створити bound function (прив'язану функцію), в яку передати значення this для функції (функція growUp() в прикладі вище).

+ +

Стрілкова функція не має власного контексту this, а використовує this з контексту вище. Тому в коді, наведеному нижче, this для функції setInterval має таке ж значення, як і this зовнішньої функції:

+ +
function Person(){
+  this.age = 0;
+
+  setInterval(() => {
+    this.age++; // |this| properly refers to the person object
+  }, 1000);
+}
+
+var p = new Person();
+ +

Relation with strict mode

+ +

Given that this comes from the surrounding lexical context, strict mode rules with regard to this are ignored.

+ +
var f = () => { 'use strict'; return this; };
+f() === window; // or the global object
+ +

All other strict mode rules apply normally.

+ +

Invoked through call or apply

+ +

Since arrow functions do not have their own this, the methods call() or apply() can only pass in parameters. thisArg is ignored.

+ +
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));         // This would log to 2
+console.log(adder.addThruCall(1)); // This would log to 2 still
+ +

No binding of arguments

+ +

Arrow functions do not have their own arguments object. Thus, in this example, arguments is simply a reference to the arguments of the enclosing scope:

+ +
var arguments = [1, 2, 3];
+var arr = () => arguments[0];
+
+arr(); // 1
+
+function foo(n) {
+  var f = () => arguments[0] + n; // foo's implicit arguments binding. arguments[0] is n
+  return f(10);
+}
+
+foo(1); // 2
+ +

In most cases, using rest parameters is a good alternative to using an arguments object.

+ +
function foo(n) {
+  var f = (...args) => args[0] + n;
+  return f(10);
+}
+
+foo(1); // 11
+ +

Arrow functions used as methods

+ +

As stated previously, arrow function expressions are best suited for non-method functions. Let's see what happens when we try to use them as methods:

+ +
'use strict';
+var obj = {
+  i: 10,
+  b: () => console.log(this.i, this),
+  c: function() {
+    console.log(this.i, this);
+  }
+}
+obj.b(); // prints undefined, Window {...} (or the global object)
+obj.c(); // prints 10, Object {...}
+ +

Arrow functions do not have their own this. Another example involving {{jsxref("Object.defineProperty()")}}:

+ +
'use strict';
+var obj = {
+  a: 10
+};
+
+Object.defineProperty(obj, 'b', {
+  get: () => {
+    console.log(this.a, typeof this.a, this);
+    return this.a + 10; // represents global object 'Window', therefore 'this.a' returns 'undefined'
+  }
+});
+
+ +

Use of the new operator

+ +

Arrow functions cannot be used as constructors and will throw an error when used with new.

+ +
var Foo = () => {};
+var foo = new Foo(); // TypeError: Foo is not a constructor
+ +

Use of prototype property

+ +

Arrow functions do not have a prototype property.

+ +
var Foo = () => {};
+console.log(Foo.prototype); // undefined
+
+ +

Use of the yield keyword

+ +

The yield keyword may not be used in an arrow function's body (except when permitted within functions further nested within it). As a consequence, arrow functions cannot be used as generators.

+ +

Тіло функції

+ +

Arrow functions can have either a "concise body" or the usual "block body".

+ +

In a concise body, only an expression is specified, which becomes the explicit return value. In a block body, you must use an explicit return statement.

+ +
var func = x => x * x;
+// concise body syntax, implied "return"
+
+var func = (x, y) => { return x + y; };
+// with block body, explicit "return" needed
+
+ +

Повернення літерала об'єкта

+ +

Keep in mind that returning object literals using the concise body syntax params => {object:literal} will not work as expected.

+ +
var func = () => { foo: 1 };
+// Calling func() returns undefined!
+
+var func = () => { foo: function() {} };
+// SyntaxError: function statement requires a name
+ +

This is because the code inside braces ({}) is parsed as a sequence of statements (i.e. foo is treated like a label, not a key in an object literal).

+ +

Remember to wrap the object literal in parentheses.

+ +
var func = () => ({foo: 1});
+ +

Розрив рядка

+ +

An arrow function cannot contain a line break between its parameters and its arrow.

+ +
var func = ()
+           => 1;
+// SyntaxError: expected expression, got '=>'
+ +

Порядок розбору

+ +

Although the arrow in an arrow function is not an operator, arrow functions have special parsing rules that interact differently with operator precedence compared to regular functions.

+ +
let callback;
+
+callback = callback || function() {}; // ok
+
+callback = callback || () => {};
+// SyntaxError: invalid arrow-function arguments
+
+callback = callback || (() => {});    // ok
+
+ +

Ще приклади

+ +
// An empty arrow function returns undefined
+let empty = () => {};
+
+(() => 'foobar')();
+// Returns "foobar"
+// (this is an Immediately Invoked Function Expression
+// see 'IIFE' in glossary)
+
+var simple = a => a > 15 ? 15 : a;
+simple(16); // 15
+simple(10); // 10
+
+let max = (a, b) => a > b ? a : b;
+
+// Easy array filtering, mapping, ...
+
+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]
+
+// More concise promise chains
+promise.then(a => {
+  // ...
+}).then(b => {
+  // ...
+});
+
+// Parameterless arrow functions that are visually easier to parse
+setTimeout( () => {
+  console.log('I happen sooner');
+  setTimeout( () => {
+    // deeper code
+    console.log('I happen later');
+  }, 1);
+}, 1);
+
+ +

Специфікації

+ + + + + + + + + + + + + + + + + + + +
СпецифікаціяСтатусКоментар
{{SpecName('ES2015', '#sec-arrow-function-definitions', 'Arrow Function Definitions')}}{{Spec2('ES2015')}}Початкова виознака.
{{SpecName('ESDraft', '#sec-arrow-function-definitions', 'Arrow Function Definitions')}}{{Spec2('ESDraft')}}
+ +

Підтримка веб-переглядачами

+ +
+ + +

{{Compat("javascript.functions.arrow_functions")}}

+
+ +

Див. також

+ + diff --git a/files/uk/web/javascript/reference/functions/rest_parameters/index.html b/files/uk/web/javascript/reference/functions/rest_parameters/index.html new file mode 100644 index 0000000000..f117aecc60 --- /dev/null +++ b/files/uk/web/javascript/reference/functions/rest_parameters/index.html @@ -0,0 +1,211 @@ +--- +title: Залишкові параметри +slug: Web/JavaScript/Reference/Functions/решта_параметрів +tags: + - JavaScript + - Rest + - параметри + - функції +translation_of: Web/JavaScript/Reference/Functions/rest_parameters +--- +
{{jsSidebar("Functions")}}
+ +
Синтаксис залишкових параметрів дозволяє представити невизначену кількість аргументів у вигляді масиву.
+ +
+ +

{{EmbedInteractiveExample("pages/js/functions-restparameters.html")}}

+ + + +

Синтаксис

+ +
function f(a, b, ...theArgs) {
+  // ...
+}
+
+ +

Опис

+ +

Перед останнім параметром функції може стояти ..., в результаті решта аргументів (наданих користувачем) будуть розміщені у  "стандартному" масиві JavaScript.

+ +

Лише останній параметр може бути "залишковим".

+ +
function myFun(a, b, ...manyMoreArgs) {
+  console.log("a", a);
+  console.log("b", b);
+  console.log("manyMoreArgs", manyMoreArgs);
+}
+
+myFun("один", "два", "три", "чорити", "п'ять", "шість");
+
+// Виведе:
+// a, один
+// b, два
+// manyMoreArgs, ["три", "чотири", "п'ять", "шість"]
+ +

Різниця між залишковими параметрами та об'єктом arguments

+ +

Існують три основні відмінності між залишковими параметрами та об'єктом {{jsxref("Functions/arguments", "arguments")}}:

+ + + +

Від arguments до масиву

+ +

Залишкові параметри були запроваджені, щоб зменшити кількість шаблонного коду, спричиненого об'єктом arguments.

+ +
// До появи залишкових параметрів, "arguments" можна було перетворити на масив таким чином:
+
+function f(a, b) {
+
+  let normalArray = Array.prototype.slice.call(arguments);
+  // -- або --
+  let normalArray = [].slice.call(arguments);
+  // -- або --
+  let normalArray = Array.from(arguments);
+
+  let first = normalArray.shift(); // OK, вертає перший аргумент
+  let first = arguments.shift(); // ERROR (arguments не є справжнім масивом)
+}
+
+// Тепер ми легко можемо отримати звичайний масив за допомогою залишкових параметрів
+
+function f(...args) {
+  let normalArray = args;
+  let first = normalArray.shift(); // OK, вертає перший аргумент
+}
+ +

Приклади

+ +

Використання залишкових параметрів

+ +

У цьому прикладі перший аргумент відповідає "a", а другий "b", отже, ці іменовані аргументи можуть використовуватись як звичайні.

+ +

Однак, третій аргумент, "manyMoreArgs", буде масивом, який містить 3-й, 4-й, 5-й, 6-й ... n-й -- стільки аргументів, скільки надасть користувач.

+ +
function myFun(a, b, ...manyMoreArgs) {
+  console.log("a", a);
+  console.log("b", b);
+  console.log("manyMoreArgs", manyMoreArgs);
+}
+
+myFun("один", "два", "три", "чотири", "п'ять", "шість");
+
+// a, один
+// b, два
+// manyMoreArgs, ["три", "чотири", "п'ять", "шість"]
+ +

Нижче... хоча тут всього одне значення, останній аргумент все одно додається у масив.

+ +
// використовуємо ту саму функцію з наведеного вище прикладу
+
+myFun("один", "два", "три");
+
+// a, один
+// b, два
+// manyMoreArgs, ["три"]
+ +

Нижче... третій аргумент не був переданий, але "manyMoreArgs" все одно є масивом (хоча й порожнім).

+ +
// використовуємо ту саму функцію з наведеного вище прикладу
+
+myFun("один", "два");
+
+// a, один
+// b, два
+// manyMoreArgs, []
+ +

Кількість аргументів

+ +

Оскільки theArgs є масивом, кількість його елементів надається властивістю length:

+ +
function fun1(...theArgs) {
+  console.log(theArgs.length);
+}
+
+fun1()         // 0
+fun1(5)        // 1
+fun1(5, 6, 7)  // 3
+ +

Звичайний параметр та залишкові параметри

+ +

У наступному прикладі залишковий параметр використовується, щоб зібрати усі аргументи після першого у масиві. Далі кожен з них помножується на перший параметр, і масив повертається:

+ +
function multiply(multiplier, ...theArgs) {
+  return theArgs.map(function(element) {
+    return multiplier * element;
+  });
+}
+
+let arr = multiply(2, 1, 2, 3);
+console.log(arr); // [2, 4, 6]
+ +

Використання з об'єктом arguments

+ +

Методи Array можуть використовуватись на залишкових параметрах, але не на об'єкті arguments:

+ +
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; // цього ніколи не станеться
+}
+
+// викидає TypeError: arguments.sort is not a function
+console.log(sortArguments(5, 3, 7, 1));
+
+ +

Щоб скористатись методами Array на об'єкті arguments, він спочатку має бути перетворений на справжній масив.

+ +
function sortArguments() {
+  var args = Array.from(arguments);
+  var sortedArgs = args.sort();
+  return sortedArgs;
+}
+console.log(sortArguments(5, 3, 7, 1)); // [1, 3, 5, 7]
+ +

Специфікації

+ + + + + + + + + + +
Специфікація
{{SpecName('ESDraft', '#sec-function-definitions', 'Function Definitions')}}
+ +

Сумісність з веб-переглядачами

+ +
+
+ + +

{{Compat("javascript.functions.rest_parameters")}}

+
+
+ +

Див. також

+ + diff --git "a/files/uk/web/javascript/reference/functions/\321\200\320\265\321\210\321\202\320\260_\320\277\320\260\321\200\320\260\320\274\320\265\321\202\321\200\321\226\320\262/index.html" "b/files/uk/web/javascript/reference/functions/\321\200\320\265\321\210\321\202\320\260_\320\277\320\260\321\200\320\260\320\274\320\265\321\202\321\200\321\226\320\262/index.html" deleted file mode 100644 index f117aecc60..0000000000 --- "a/files/uk/web/javascript/reference/functions/\321\200\320\265\321\210\321\202\320\260_\320\277\320\260\321\200\320\260\320\274\320\265\321\202\321\200\321\226\320\262/index.html" +++ /dev/null @@ -1,211 +0,0 @@ ---- -title: Залишкові параметри -slug: Web/JavaScript/Reference/Functions/решта_параметрів -tags: - - JavaScript - - Rest - - параметри - - функції -translation_of: Web/JavaScript/Reference/Functions/rest_parameters ---- -
{{jsSidebar("Functions")}}
- -
Синтаксис залишкових параметрів дозволяє представити невизначену кількість аргументів у вигляді масиву.
- -
- -

{{EmbedInteractiveExample("pages/js/functions-restparameters.html")}}

- - - -

Синтаксис

- -
function f(a, b, ...theArgs) {
-  // ...
-}
-
- -

Опис

- -

Перед останнім параметром функції може стояти ..., в результаті решта аргументів (наданих користувачем) будуть розміщені у  "стандартному" масиві JavaScript.

- -

Лише останній параметр може бути "залишковим".

- -
function myFun(a, b, ...manyMoreArgs) {
-  console.log("a", a);
-  console.log("b", b);
-  console.log("manyMoreArgs", manyMoreArgs);
-}
-
-myFun("один", "два", "три", "чорити", "п'ять", "шість");
-
-// Виведе:
-// a, один
-// b, два
-// manyMoreArgs, ["три", "чотири", "п'ять", "шість"]
- -

Різниця між залишковими параметрами та об'єктом arguments

- -

Існують три основні відмінності між залишковими параметрами та об'єктом {{jsxref("Functions/arguments", "arguments")}}:

- - - -

Від arguments до масиву

- -

Залишкові параметри були запроваджені, щоб зменшити кількість шаблонного коду, спричиненого об'єктом arguments.

- -
// До появи залишкових параметрів, "arguments" можна було перетворити на масив таким чином:
-
-function f(a, b) {
-
-  let normalArray = Array.prototype.slice.call(arguments);
-  // -- або --
-  let normalArray = [].slice.call(arguments);
-  // -- або --
-  let normalArray = Array.from(arguments);
-
-  let first = normalArray.shift(); // OK, вертає перший аргумент
-  let first = arguments.shift(); // ERROR (arguments не є справжнім масивом)
-}
-
-// Тепер ми легко можемо отримати звичайний масив за допомогою залишкових параметрів
-
-function f(...args) {
-  let normalArray = args;
-  let first = normalArray.shift(); // OK, вертає перший аргумент
-}
- -

Приклади

- -

Використання залишкових параметрів

- -

У цьому прикладі перший аргумент відповідає "a", а другий "b", отже, ці іменовані аргументи можуть використовуватись як звичайні.

- -

Однак, третій аргумент, "manyMoreArgs", буде масивом, який містить 3-й, 4-й, 5-й, 6-й ... n-й -- стільки аргументів, скільки надасть користувач.

- -
function myFun(a, b, ...manyMoreArgs) {
-  console.log("a", a);
-  console.log("b", b);
-  console.log("manyMoreArgs", manyMoreArgs);
-}
-
-myFun("один", "два", "три", "чотири", "п'ять", "шість");
-
-// a, один
-// b, два
-// manyMoreArgs, ["три", "чотири", "п'ять", "шість"]
- -

Нижче... хоча тут всього одне значення, останній аргумент все одно додається у масив.

- -
// використовуємо ту саму функцію з наведеного вище прикладу
-
-myFun("один", "два", "три");
-
-// a, один
-// b, два
-// manyMoreArgs, ["три"]
- -

Нижче... третій аргумент не був переданий, але "manyMoreArgs" все одно є масивом (хоча й порожнім).

- -
// використовуємо ту саму функцію з наведеного вище прикладу
-
-myFun("один", "два");
-
-// a, один
-// b, два
-// manyMoreArgs, []
- -

Кількість аргументів

- -

Оскільки theArgs є масивом, кількість його елементів надається властивістю length:

- -
function fun1(...theArgs) {
-  console.log(theArgs.length);
-}
-
-fun1()         // 0
-fun1(5)        // 1
-fun1(5, 6, 7)  // 3
- -

Звичайний параметр та залишкові параметри

- -

У наступному прикладі залишковий параметр використовується, щоб зібрати усі аргументи після першого у масиві. Далі кожен з них помножується на перший параметр, і масив повертається:

- -
function multiply(multiplier, ...theArgs) {
-  return theArgs.map(function(element) {
-    return multiplier * element;
-  });
-}
-
-let arr = multiply(2, 1, 2, 3);
-console.log(arr); // [2, 4, 6]
- -

Використання з об'єктом arguments

- -

Методи Array можуть використовуватись на залишкових параметрах, але не на об'єкті arguments:

- -
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; // цього ніколи не станеться
-}
-
-// викидає TypeError: arguments.sort is not a function
-console.log(sortArguments(5, 3, 7, 1));
-
- -

Щоб скористатись методами Array на об'єкті arguments, він спочатку має бути перетворений на справжній масив.

- -
function sortArguments() {
-  var args = Array.from(arguments);
-  var sortedArgs = args.sort();
-  return sortedArgs;
-}
-console.log(sortArguments(5, 3, 7, 1)); // [1, 3, 5, 7]
- -

Специфікації

- - - - - - - - - - -
Специфікація
{{SpecName('ESDraft', '#sec-function-definitions', 'Function Definitions')}}
- -

Сумісність з веб-переглядачами

- -
-
- - -

{{Compat("javascript.functions.rest_parameters")}}

-
-
- -

Див. також

- - diff --git "a/files/uk/web/javascript/reference/functions/\321\201\321\202\321\200\321\226\320\273\320\272\320\276\320\262\321\226_\321\204\321\203\320\275\320\272\321\206\321\226\321\227/index.html" "b/files/uk/web/javascript/reference/functions/\321\201\321\202\321\200\321\226\320\273\320\272\320\276\320\262\321\226_\321\204\321\203\320\275\320\272\321\206\321\226\321\227/index.html" deleted file mode 100644 index f1638d8d84..0000000000 --- "a/files/uk/web/javascript/reference/functions/\321\201\321\202\321\200\321\226\320\273\320\272\320\276\320\262\321\226_\321\204\321\203\320\275\320\272\321\206\321\226\321\227/index.html" +++ /dev/null @@ -1,362 +0,0 @@ ---- -title: Стрілкові функції -slug: Web/JavaScript/Reference/Functions/Стрілкові_функції -translation_of: Web/JavaScript/Reference/Functions/Arrow_functions ---- -
{{jsSidebar("Functions")}}
- -

Вирази стрілкових функцій мають більш короткий синтаксис, аніж функціональні вирази і не мають свого власного this, arguments, super, і new.target. Вони не можуть бути використані як конструктор і завжди анонімні.

- -

Синтаксис

- -

Basic Syntax

- -
(параметр1,параметр2, …, параметрN) => { оператори }
-(параметр1, параметр2, …, параметрN) => вираз
-// еквівалентно до запису: (параметр1,параметр2, …, параметрN) => { return вираз; }
-
-// Якщо у функції тільки один параметр, то дужки не обов'язкові:
-(параметр) => { оператори }
-параметр => { оператори }
-параметр => вираз
-
-
-// Список параметрів для функції без параметрів повинен бути записаний у парі фігурних дужок.
-() => { оператори }
-
- -

Advanced Syntax

- -
// Візьміть тіло функції у дужки, якщо вона повертає об'єкт
-params => ({foo: bar})
-
-// Залишкові параметри та параметри за замовчуванням підтримуються як і в звичайних функціях
-(параметр1, параметр2, ...залишкові параметри) => { оператори }
-(параметр1 = значення_за_замовчуванням, параметр2, …, параметрN = значення_за_замовчуваннямN) => { оператори }
-
-// Деструктиризація в списку параметрів також підтримується:
-let f = ([a, b] = [1, 2], {x: c} = {x: a + b}) => a + b + c;
-f();
-// 6
-
- -

Опис

- -

Див. також "ES6 In Depth: Arrow functions" on hacks.mozilla.org.

- -

Появу стрілкових функцій зумовили два фактори: можливість більш короткого запису і випадки, коли сутність this не обов'язкова.

- -

Коротший запис

- -
var materials = [
-  'Hydrogen',
-  'Helium',
-  'Lithium',
-  'Beryllium'
-];
-
-materials.map(function(material) {
-  return material.length;
-}); // [8, 6, 7, 9]
-
-materials.map((material) => {
-  return material.length;
-}); // [8, 6, 7, 9]
-
-materials.map(material => material.length); // [8, 6, 7, 9]
-
- -

Спільний this

- -

До появи стрілкових функцій кожна нова функція мала власне значення this :

- - - -

Це все було далеким від ідеалів об'єктно-орієнтованого програмування.

- -
function Person() {
-  // The Person() constructor defines `this` as an instance of itself.
-  this.age = 0;
-
-  setInterval(function growUp() {
-    // In non-strict mode, the growUp() function defines `this`
-    // as the global object, which is different from the `this`
-    // defined by the Person() constructor.
-    this.age++;
-  }, 1000);
-}
-
-var p = new Person();
- -

В ECMAScript 3/5 ця проблема вирішувалась шляхом присвоєння значення this змінній, оголошеній всередині функції.

- -
function Person() {
-  var that = this;
-  that.age = 0;
-
-  setInterval(function growUp() {
-    // The callback refers to the `that` variable of which
-    // the value is the expected object.
-    that.age++;
-  }, 1000);
-}
- -

Або можна створити bound function (прив'язану функцію), в яку передати значення this для функції (функція growUp() в прикладі вище).

- -

Стрілкова функція не має власного контексту this, а використовує this з контексту вище. Тому в коді, наведеному нижче, this для функції setInterval має таке ж значення, як і this зовнішньої функції:

- -
function Person(){
-  this.age = 0;
-
-  setInterval(() => {
-    this.age++; // |this| properly refers to the person object
-  }, 1000);
-}
-
-var p = new Person();
- -

Relation with strict mode

- -

Given that this comes from the surrounding lexical context, strict mode rules with regard to this are ignored.

- -
var f = () => { 'use strict'; return this; };
-f() === window; // or the global object
- -

All other strict mode rules apply normally.

- -

Invoked through call or apply

- -

Since arrow functions do not have their own this, the methods call() or apply() can only pass in parameters. thisArg is ignored.

- -
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));         // This would log to 2
-console.log(adder.addThruCall(1)); // This would log to 2 still
- -

No binding of arguments

- -

Arrow functions do not have their own arguments object. Thus, in this example, arguments is simply a reference to the arguments of the enclosing scope:

- -
var arguments = [1, 2, 3];
-var arr = () => arguments[0];
-
-arr(); // 1
-
-function foo(n) {
-  var f = () => arguments[0] + n; // foo's implicit arguments binding. arguments[0] is n
-  return f(10);
-}
-
-foo(1); // 2
- -

In most cases, using rest parameters is a good alternative to using an arguments object.

- -
function foo(n) {
-  var f = (...args) => args[0] + n;
-  return f(10);
-}
-
-foo(1); // 11
- -

Arrow functions used as methods

- -

As stated previously, arrow function expressions are best suited for non-method functions. Let's see what happens when we try to use them as methods:

- -
'use strict';
-var obj = {
-  i: 10,
-  b: () => console.log(this.i, this),
-  c: function() {
-    console.log(this.i, this);
-  }
-}
-obj.b(); // prints undefined, Window {...} (or the global object)
-obj.c(); // prints 10, Object {...}
- -

Arrow functions do not have their own this. Another example involving {{jsxref("Object.defineProperty()")}}:

- -
'use strict';
-var obj = {
-  a: 10
-};
-
-Object.defineProperty(obj, 'b', {
-  get: () => {
-    console.log(this.a, typeof this.a, this);
-    return this.a + 10; // represents global object 'Window', therefore 'this.a' returns 'undefined'
-  }
-});
-
- -

Use of the new operator

- -

Arrow functions cannot be used as constructors and will throw an error when used with new.

- -
var Foo = () => {};
-var foo = new Foo(); // TypeError: Foo is not a constructor
- -

Use of prototype property

- -

Arrow functions do not have a prototype property.

- -
var Foo = () => {};
-console.log(Foo.prototype); // undefined
-
- -

Use of the yield keyword

- -

The yield keyword may not be used in an arrow function's body (except when permitted within functions further nested within it). As a consequence, arrow functions cannot be used as generators.

- -

Тіло функції

- -

Arrow functions can have either a "concise body" or the usual "block body".

- -

In a concise body, only an expression is specified, which becomes the explicit return value. In a block body, you must use an explicit return statement.

- -
var func = x => x * x;
-// concise body syntax, implied "return"
-
-var func = (x, y) => { return x + y; };
-// with block body, explicit "return" needed
-
- -

Повернення літерала об'єкта

- -

Keep in mind that returning object literals using the concise body syntax params => {object:literal} will not work as expected.

- -
var func = () => { foo: 1 };
-// Calling func() returns undefined!
-
-var func = () => { foo: function() {} };
-// SyntaxError: function statement requires a name
- -

This is because the code inside braces ({}) is parsed as a sequence of statements (i.e. foo is treated like a label, not a key in an object literal).

- -

Remember to wrap the object literal in parentheses.

- -
var func = () => ({foo: 1});
- -

Розрив рядка

- -

An arrow function cannot contain a line break between its parameters and its arrow.

- -
var func = ()
-           => 1;
-// SyntaxError: expected expression, got '=>'
- -

Порядок розбору

- -

Although the arrow in an arrow function is not an operator, arrow functions have special parsing rules that interact differently with operator precedence compared to regular functions.

- -
let callback;
-
-callback = callback || function() {}; // ok
-
-callback = callback || () => {};
-// SyntaxError: invalid arrow-function arguments
-
-callback = callback || (() => {});    // ok
-
- -

Ще приклади

- -
// An empty arrow function returns undefined
-let empty = () => {};
-
-(() => 'foobar')();
-// Returns "foobar"
-// (this is an Immediately Invoked Function Expression
-// see 'IIFE' in glossary)
-
-var simple = a => a > 15 ? 15 : a;
-simple(16); // 15
-simple(10); // 10
-
-let max = (a, b) => a > b ? a : b;
-
-// Easy array filtering, mapping, ...
-
-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]
-
-// More concise promise chains
-promise.then(a => {
-  // ...
-}).then(b => {
-  // ...
-});
-
-// Parameterless arrow functions that are visually easier to parse
-setTimeout( () => {
-  console.log('I happen sooner');
-  setTimeout( () => {
-    // deeper code
-    console.log('I happen later');
-  }, 1);
-}, 1);
-
- -

Специфікації

- - - - - - - - - - - - - - - - - - - -
СпецифікаціяСтатусКоментар
{{SpecName('ES2015', '#sec-arrow-function-definitions', 'Arrow Function Definitions')}}{{Spec2('ES2015')}}Початкова виознака.
{{SpecName('ESDraft', '#sec-arrow-function-definitions', 'Arrow Function Definitions')}}{{Spec2('ESDraft')}}
- -

Підтримка веб-переглядачами

- -
- - -

{{Compat("javascript.functions.arrow_functions")}}

-
- -

Див. також

- - -- cgit v1.2.3-54-g00ecf