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

by 2 contributors:

Это экспериментальная технология, часть предложения Harmony (ECMAScript 6).
Поскольку спецификация этой технологии ещё не стабилизировалась, проверьте таблицу совместимости её использования в различных браузерах. Также обратите внимание, что синтаксис и поведение экспериментальной технологии могут быть изменены в будущих версиях браузеров в соответствии с изменениями в спецификации.

Сводка

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

Синтаксис

([параметр] [, параметр]) => {
   операторы
}

параметр => выражение

Подробные примеры синтаксиса можно посмотреть здесь.

Параметры

параметр
Название аргумента. Отсутствие аргументов должно быть показано при помощи (). Для единственного аргумента круглые скобки не обязательны, например, foo => 1
операторы или выражение
Несколько операторов должны быть заключены в фигурные скобки, {}. Однако, единственное выражение не требует скобок. При этом выражение также явно задаёт возвращаемое значение функции.

Описание

Два фактора повлияли на появление стрелочных функции: более короткий синтаксис и лексика this.

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

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

var a = [
  "Hydrogen",
  "Helium",
  "Lithium",
  "Beryl­lium"
];

var a2 = a.map(function(s){ return s.length });

var a3 = a.map( s => s.length );

Лексика this

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

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 близко расположенной переменной:

function Person() {
  var self = this; // Некоторые выбирают `that` вместо `self`. 
                   // Выберите один вариант и следуйте ему.
  self.age = 0;

  setInterval(function growUp() {
    // В функции используется переменная `self`, которая
    // имеет значение требуемого объекта.
    self.age++;
  }, 1000);
}

Также, может быть создана привязанная функция, в которой задаётся требуемое значение this для функции growUp.

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

function Person(){
  this.age = 0;

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

var p = new Person();

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

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

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

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

Примеры

// Пустая стрелочная функция возвращает undefined
let empty = () => {};

(() => "foobar")() // вернёт "foobar" 

var simple = a => a > 15 ? 15 : a; 
simple(16); // 15
simple(10); // 10

var complex = (a, b) => {
    if (a > b) {
        return a;
    } else {
        return b;
    }
}

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

Спецификация Статус Комментарий
ECMAScript 6 (ECMA-262)
Определение 'Arrow Function Definitions' в этой спецификации.
Кандидат в рекомендации Изначальное определение.

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

Возможность Chrome Firefox (Gecko) Internet Explorer Opera Safari
Базовая поддержка Нет 22.0 (22.0) Нет Нет Нет
Возможность Android Chrome for Android Firefox Mobile (Gecko) IE Mobile Opera Mobile Safari Mobile
Базовая поддержка Нет (Да) 22.0 (22.0) Нет Нет Нет

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

  • Первоначальная реализация стрелочных функций в Firefox автоматически переводила их в строгий режим. Это поведение было изменено в Firefox 24. Использование "use strict"; стало обязательным.
  • Стрелочные функции семантически отличаются от нестандартных Expression Closures, добавленных в Firefox 3 (подробности в Javascript 1.8); в Expression Closures значение this не привязано лексически.

Метки документа и участники

Contributors to this page: pashutk, dtretyakov
Обновлялась последний раз: pashutk,
Скрыть боковую панель