Кратко
СкопированоСтрелочная функция это короткая запись функционального выражения (function expression) без собственных привязок this
, arguments
и super
.
Как пишется
СкопированоЕсли функция принимает только один аргумент, круглые скобки вокруг него можно не ставить. Если тело функции состоит из одного выражения, оператор return
также необязателен.
const divider = n => n / 2
const divider = n => n / 2
Если тело функции содержит несколько выражений, оберните их в фигурные скобки. Здесь оператор return
нужен, так как функция что-то возвращает.
const sayHello = (name) => { const greeting = `Hello ${name}` return greeting}
const sayHello = (name) => { const greeting = `Hello ${name}` return greeting }
Как понять
СкопированоСтрелочные функции пишутся короче:
// Обычная функцияfunction divider(n) { return n / 2}// Стрелочная функцияconst divider = n => n / 2
// Обычная функция function divider(n) { return n / 2 } // Стрелочная функция const divider = n => n / 2
У стрелочных функций нет своих привязок для arguments
, super
, this
или new
. Значения этих ключевых слов привязываются к внешнему лексическому окружению.
Использование call
или apply
никак не влияет на стрелочные функции.
class Person { constructor(name) { this.name = name } sayName() { console.log(this.name) } sayNameWithArrowFunction = () => { console.log(this.name) }}const alex = new Person('Alex')console.log(alex.sayName())// Alexconsole.log(alex.sayNameWithArrowFunction())// Alexconst den = new Person('Den')console.log(alex.sayName.call(den))// Denconsole.log(alex.sayNameWithArrowFunction.call(den))// Alex, т. к. не изменить контекст
class Person { constructor(name) { this.name = name } sayName() { console.log(this.name) } sayNameWithArrowFunction = () => { console.log(this.name) } } const alex = new Person('Alex') console.log(alex.sayName()) // Alex console.log(alex.sayNameWithArrowFunction()) // Alex const den = new Person('Den') console.log(alex.sayName.call(den)) // Den console.log(alex.sayNameWithArrowFunction.call(den)) // Alex, т. к. не изменить контекст
В теле стрелочных функций arguments
будет ссылаться на arguments
из внешней лексической области:
function f() { const arrowFunction = () => { console.log(arguments) } arrowFunction('стрелочная функция')}f('обычная функция')// { 0: 'обычная функция', length: 1 }
function f() { const arrowFunction = () => { console.log(arguments) } arrowFunction('стрелочная функция') } f('обычная функция') // { 0: 'обычная функция', length: 1 }
У стрелочных функций нет свойств сonstructor
и prototype
:
const arrowFunction = () => {}console.log(arrowFunction.prototype)// undefined
const arrowFunction = () => {} console.log(arrowFunction.prototype) // undefined
И, как следствие, стрелочные функции не могут быть использованы как конструктор. Их нельзя использовать с оператором new
.
const arrowFunction = () => {}console.log(new arrowFunction())// TypeError: arrowFunction is not a constructor
const arrowFunction = () => {} console.log(new arrowFunction()) // TypeError: arrowFunction is not a constructor
Стрелочные функции нельзя использоваться как генераторы. Ключевое слово super
внутри стрелочных функциях ссылается на super
из внешнего лексического окружения, а не на super
родительского класса.
До появления стрелочных функций возникали проблемы с использованием this
внутри функций-колбеков. Посмотрите на пример с set
.
const obj = { count: 10, doSomethingLater() { setTimeout(function () { // Тут this ссылается на объект Window this.count++ console.log(this.count) }, 1000) },};obj.doSomethingLater()// "NaN"
const obj = { count: 10, doSomethingLater() { setTimeout(function () { // Тут this ссылается на объект Window this.count++ console.log(this.count) }, 1000) }, }; obj.doSomethingLater() // "NaN"
В колбэк-функции set
this
указывет на объект Window
, а не на obj
, поэтому значение this
оказывается неверным.
Поэтому приходилось использовать различные методы для передачи контекста внутрь колбэка.
Например, при помощи bind
:
const obj = { count: 10, doSomethingLater() { setTimeout(function () { this.count++ console.log(this.count) }.bind(this), 1000) },}obj.doSomethingLater()// 11
const obj = { count: 10, doSomethingLater() { setTimeout(function () { this.count++ console.log(this.count) }.bind(this), 1000) }, } obj.doSomethingLater() // 11
Также использовался хак с переменной that
, где сохранялся контекст this
, и внутри колбэка уже использовалась эта переменная:
const obj = { count: 10, doSomethingLater() { const that = this setTimeout(function () { that.count++ console.log(that.count) }, 1000) },}obj.doSomethingLater()// 11
const obj = { count: 10, doSomethingLater() { const that = this setTimeout(function () { that.count++ console.log(that.count) }, 1000) }, } obj.doSomethingLater() // 11
С появлением стрелочных функций в качестве колбэков, больше не нужно беспокоиться о правильной привязке this
, так как их контекст выполнения привязан к лексической области видимости.
const obj = { count: 10, doSomethingLater() { setTimeout(() => { this.count++ console.log(this.count) }, 1000) },}obj.doSomethingLater()// 11
const obj = { count: 10, doSomethingLater() { setTimeout(() => { this.count++ console.log(this.count) }, 1000) }, } obj.doSomethingLater() // 11