Кратко
СкопированоСтрелочная функция это короткая запись функционального выражения (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