Movatterモバイル変換


[0]ホーム

URL:


MDN Web Docs

Эта страница была переведена с английского языка силами сообщества. Вы тоже можете внести свой вклад, присоединившись к русскоязычному сообществу MDN Web Docs.

Стрелочные функции

BaselineWidely available

Сводка

Выражения стрелочных функций имеют более короткий синтаксис по сравнению сфункциональными выражениями и лексически привязаны к значениюthis (но не привязаны к собственномуthis,arguments,super, илиnew.target). Выражение стрелочных функций не позволяют задавать имя, поэтому стрелочные функциианонимны, если их ни к чему не присвоить.

Синтаксис

Базовый синтаксис

js
(param1, param2, …, paramN) => { statements }(param1, param2, …, paramN) => expression// эквивалентно: (param1, param2, …, paramN) => { return expression; }// Круглые скобки не обязательны для единственного параметра:(singleParam) => { statements }singleParam => { statements }// Функция без параметров нуждается в круглых скобках:() => { statements }() => expression// Эквивалентно: () => { return expression; }

Расширенный синтаксис

js
// Когда возвращаете литеральное выражение объекта, заключите тело в скобкиparams => ({foo: bar})// Остаточные параметры и параметры по умолчанию поддерживаются(param1, param2, ...rest) => { statements }(param1 = defaultValue1, param2, …, paramN = defaultValueN) => { statements }// Деструктуризация тоже поддерживаетсяvar 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.

Короткие функции

В некоторых функциональных шаблонах приветствуются более короткие функции. Сравните:

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]

Отсутствие связывания сthis

До появления стрелочных функций, каждая новая функция имела своё значениеthis (новый объект в случае конструктора, undefined вstrict режиме вызова функции, контекст объекта при вызове функции как "метода объекта" и т.д.). Это очень раздражало при использовании объектно-ориентированного стиля программирования.

js
function Person() {  // В конструкторе Person() `this` указывает на себя.  this.age = 0;  setInterval(function growUp() {    // В нестрогом режиме, в функции growUp() `this` указывает    // на глобальный объект, который отличается от `this`,    // определяемом в конструкторе Person().    this.age++;  }, 1000);}var p = new Person();

В ECMAScript 3/5, данная проблема решалась присваиванием значенияthis переменной:

js
function Person() {  var that = this;  that.age = 0;  setInterval(function growUp() {    // Функция с обратным вызовом(callback) содержит переменную that, которая    // ссылается на требуемый объект this.    that.age++;  }, 1000);}

Кроме этого, может быть созданапривязанная функция, в которую передаётся требуемое значениеthis для функции (функцияgrowUp() в примере выше).

Стрелочные функции не содержат собственный контекстthis, а используют значениеthis окружающего контекста. Поэтому нижеприведённый код работает как предполагалось:

js
function Person() {  this.age = 0;  setInterval(() => {    this.age++; // `this` указывает на объект Person  }, 1000);}var p = new Person();

Строгий режим исполнения

Поскольку значениеthis определяется лексикой, правила строгого режима (strict mode) относительноthis игнорируются:

js
var f = () => {  "use strict";  return this;};f() === window; // или глобальный объект

Все остальные правила строгого режима применяются как обычно.

Вызов с помощью call или apply

Так как значениеthis определяется лексикой, вызов стрелочных функций с помощью методовcall() илиapply(), даже если передать аргументы в эти методы, не влияет на значениеthis:

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)); // Выводит 2console.log(adder.addThruCall(1)); // Всё равно выводит 2

Не имеет собственного объекта arguments

Стрелочные функции не имеют собственного объекта arguments, поэтому в теле стрелочных функций arguments будет ссылаться на переменную в окружающей области.

js
var arguments = 42;var arr = () => arguments;arr(); // 42function foo() {  var f = (i) => arguments[0] + i; // Неявное связывание ссылки arguments  // стрелочной функции f  // c объектом arguments функции foo  return f(2);}foo(1); // 3

В большинстве случаев лучшей заменой объекта arguments в стрелочных функциях являютсяостаточные параметры:

js
function foo() {  var f = (...args) => args[0];  return f(2);}foo(1); // 2

Использование стрелочных функций как методов

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

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 {...}

Стрелочные функции не объявляют привязку ("bind") их контекстаthis. Другой пример включаетObject.defineProperty():

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'  },});

Использование оператораnew

Стрелочные функции не могут быть использованы как конструктор и вызовут ошибку при использовании сnew:

js
var a = new (function () {})();// переменной "a" будет присвоено значение экземпляра анонимной функцииvar b = new (() => {})();// будет выброшено исключение// Uncaught TypeError: (intermediate value) is not a constructor

Использование ключевого словаyield

Ключевое словоyield не может быть использовано в теле стрелочной функции (за исключением случаев, когда разрешается использовать в функциях, вложенных в тело стрелочной функции). Как следствие стрелочные функции не могут быть использованы как генераторы.

Тело функции

Тело стрелочной функции может иметь краткую (concise body) или блочную (block body) форму.

Блочная форма не возвращает значение, необходимо явно вернуть значение.

js
var func = (x) => x * x; // краткий синтаксис,// неявно возвращает результатvar func = (x, y) => {  return x + y;}; // блочный синтаксис,// явно возвращает результат

Возвращаемые объектные строки (литералы)

Помните о том, что возвращаемыеобъектные строки используют сокращённый синтаксис:params => {object:literal} будет работать не так, как ожидается.

js
var func = () => { foo: 1 };// Вызов func() возвращает undefined!var func = () => { foo: function() {} };// SyntaxError: function statement requires a name

Это происходит потому что код в скобках ({}) распознаётся как цепочка выражений (т.е.foo трактуется как наименование, а не как ключ в объектной строке).

Не забывайте оборачивать скобками объектные строки.

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

Разрывы строк

Стрелочная функция не может содержать разрывы строк между параметрами и стрелкой.

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

Разбор порядка следования

Поскольку стрелка в стрелочной функции не является оператором, то стрелочные функции имеют специальные правила разбора (парсинга), которые взаимодействуют сприоритетами операторов иначе, чем в обычных функциях.

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

Больше примеров

js
// Пустая стрелочная функция возвращает undefinedlet empty = () => {};(() => "foobar")();// Вернёт "foobar"// (Это Immediately Invoked Function Expression// смотри 'IIFE' в справочнике)var simple = (a) => (a > 15 ? 15 : a);simple(16); // 15simple(10); // 10let 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);// 66var 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);

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

Specification
ECMAScript® 2026 Language Specification
# sec-arrow-function-definitions

Совместимость с браузерами

Замечания для Firefox

  • Первоначальная реализация стрелочных функций в Firefox автоматически переводила их в строгий режим. Это поведение было изменено вFirefox 24. Использование"use strict"; стало обязательным.
  • Стрелочные функции семантически отличаются от нестандартныхExpression Closures, добавленных вFirefox 3 (подробности вJavascript 1.8); в Expression Closures значениеthis не привязано лексически.
  • ДоFirefox 39, перенос строки (\n) был ошибочно разрешён после аргументов стрелочной функции. Это было исправлено для соблюдения спецификации ES2015, и код вроде:() \n => {} теперь вызываетSyntaxError в этой и более поздних версиях.

Смотрите также

Help improve MDN

Learn how to contribute.

This page was last modified on byMDN contributors.


[8]ページ先頭

©2009-2025 Movatter.jp