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 +++++++++++++++++++++ 1 file changed, 362 insertions(+) create mode 100644 files/uk/web/javascript/reference/functions/arrow_functions/index.html (limited to 'files/uk/web/javascript/reference/functions/arrow_functions/index.html') 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")}}

+
+ +

Див. також

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