Недоволен другими ответами. Ответ с наибольшим количеством голосов на 2019/3/13 фактически неверен.
Краткая версия =>
означает, что это ярлык, пишущий функцию и привязывающий ее к текущейthis
const foo = a => a * 2;
Эффективно ярлык для
const foo = function(a) { return a * 2; }.bind(this);
Вы можете увидеть все вещи, которые были сокращены. Нам не нужно function
, ни, return
ни, .bind(this)
ни фигурные скобки или скобки
Немного более длинный пример функции со стрелкой может быть
const foo = (width, height) => {
const area = width * height;
return area;
};
Показано, что если нам нужно несколько аргументов функции, нам нужны круглые скобки, а если мы хотим написать больше, чем одно выражение, нам нужны фигурные скобки и явный return
.
Важно понимать .bind
часть, и это большая тема. Это связано с тем, что this
означает в JavaScript.
ВСЕ функции имеют неявный параметр с именем this
. Как this
устанавливается при вызове функции, зависит от того, как вызывается эта функция.
принимать
function foo() { console.log(this); }
Если вы называете это нормально
function foo() { console.log(this); }
foo();
this
будет глобальным объектом.
Если вы в строгом режиме
`use strict`;
function foo() { console.log(this); }
foo();
// or
function foo() {
`use strict`;
console.log(this);
}
foo();
Это будет undefined
Вы можете установить this
непосредственно с помощью call
илиapply
function foo(msg) { console.log(msg, this); }
const obj1 = {abc: 123}
const obj2 = {def: 456}
foo.call(obj1, 'hello'); // prints Hello {abc: 123}
foo.apply(obj2, ['hi']); // prints Hi {def: 456}
Вы также можете установить this
неявно с помощью оператора точки.
function foo(msg) { console.log(msg, this); }
const obj = {
abc: 123,
bar: foo,
}
obj.bar('Hola'); // prints Hola {abc:123, bar: f}
Проблема возникает, когда вы хотите использовать функцию в качестве обратного вызова или слушателя. Вы создаете класс и хотите назначить функцию в качестве обратного вызова, который обращается к экземпляру класса.
class ShowName {
constructor(name, elem) {
this.name = name;
elem.addEventListener('click', function() {
console.log(this.name); // won't work
});
}
}
Код выше не будет работать, потому что когда элемент запускает событие и вызывает функцию, this
значение не будет экземпляром класса.
Одним из распространенных способов решения этой проблемы является использование .bind
class ShowName {
constructor(name, elem) {
this.name = name;
elem.addEventListener('click', function() {
console.log(this.name);
}.bind(this); // <=========== ADDED! ===========
}
}
Поскольку синтаксис стрелки делает то же самое, что мы можем написать
class ShowName {
constructor(name, elem) {
this.name = name;
elem.addEventListener('click',() => {
console.log(this.name);
});
}
}
bind
эффективно делает новую функцию . Если bind
бы не существовало, вы могли бы в принципе сделать свой собственный, как это
function bind(funcitonToBind, valueToUseForThis) {
return function(...args) {
functionToBind.call(valueToUseForThis, ...args);
};
}
В старом JavaScript без оператора распространения это было бы
function bind(funcitonToBind, valueToUseForThis) {
return function() {
functionToBind.apply(valueToUseForThis, arguments);
};
}
Понимание того, что код требует понимания замыканий, но короткая версия bind
создает новую функцию, которая всегда вызывает исходную функцию со this
значением, которое было ей присвоено. Функция стрелки делает то же самое, так как они являются ярлыком дляbind(this)