Недоволен другими ответами. Ответ с наибольшим количеством голосов на 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)