ДЛ: Нет! Функции стрелок и объявления / выражения функций не эквивалентны и не могут быть заменены вслепую.
Если функция, которую вы хотите заменить, не используетthis , argumentsа не вызывается new, то да.
Как так часто: это зависит . Функции со стрелками ведут себя иначе, чем объявления / выражения функций, поэтому давайте сначала посмотрим на различия:
1. Лексический thisиarguments
Функции стрелок не имеют своих собственных thisили argumentsобязательных. Вместо этого эти идентификаторы разрешаются в лексической области, как и любая другая переменная. Это означает, что внутри функции стрелки thisи argumentsв отношении значений thisи argumentsв среде, в которой определена функция стрелки (т. Е. «Вне» функции стрелки):
// Example using a function expression
function createObject() {
console.log('Inside `createObject`:', this.foo);
return {
foo: 42,
bar: function() {
console.log('Inside `bar`:', this.foo);
},
};
}
createObject.call({foo: 21}).bar(); // override `this` inside createObject
// Example using a arrow function
function createObject() {
console.log('Inside `createObject`:', this.foo);
return {
foo: 42,
bar: () => console.log('Inside `bar`:', this.foo),
};
}
createObject.call({foo: 21}).bar(); // override `this` inside createObject
В случае выражения функции thisссылается на объект, который был создан внутри createObject. В функции стрелка случае, thisотносится к thisо createObjectсебе.
Это делает функции стрелок полезными, если вам нужен доступ thisк текущей среде:
// currently common pattern
var that = this;
getData(function(data) {
that.data = data;
});
// better alternative with arrow functions
getData(data => {
this.data = data;
});
Обратите внимание , что это также означает , что является не возможно установить функцию Эрроуthis с .bindили .call.
Если вы не очень знакомы с this, подумайте о чтении
2. Функции стрелок не могут быть вызваны с new
ES2015 различает функции, вызов в состоянии и функции, которые сооружать состоянии. Если функция конструируема, ее можно вызвать с помощью new, т.е.new User() . Если функция вызывается, она может быть вызвана без new(т.е. нормальный вызов функции).
Функции, созданные с помощью объявлений / выражений функций, являются как конструируемыми, так и вызываемыми.
Функции стрелок (и методы) могут быть вызваны только.
classконструкторы только конструктивны.
Если вы пытаетесь вызвать не вызываемую функцию или создать не конструируемую функцию, вы получите ошибку во время выполнения.
Зная это, мы можем утверждать следующее.
Сменная:
- Функции, которые не используют
this или arguments.
- Функции, которые используются с
.bind(this)
Не подлежит замене:
- Функции конструктора
- Функция / методы, добавленные в прототип (потому что они обычно используют
this )
- Variadic функции (если они используют
arguments(см. Ниже))
Давайте посмотрим на это подробнее, используя ваши примеры:
Функция конструктора
Это не будет работать, потому что функции стрелок не могут быть вызваны с new. Продолжайте использовать объявление функции / выражение или использование class.
Методы прототипа
Скорее всего, нет, потому что методы-прототипы обычно используют thisдля доступа к экземпляру. Если они не используют this, то вы можете заменить его. Однако, если вы в первую очередь заботитесь о кратком синтаксисе, используйте classего с кратким синтаксисом метода:
class User {
constructor(name) {
this.name = name;
}
getName() {
return this.name;
}
}
Методы объекта
Аналогично для методов в литерале объекта. Если метод хочет обратиться к самому объекту через this, продолжайте использовать выражения функции или используйте синтаксис нового метода:
const obj = {
getName() {
// ...
},
};
Callbacks
Это зависит. Вы обязательно должны заменить его, если вы используете псевдонимы внешнего интерфейса thisили используете .bind(this):
// old
setTimeout(function() {
// ...
}.bind(this), 500);
// new
setTimeout(() => {
// ...
}, 500);
Но: если код, который вызывает обратный вызов, явно устанавливает thisопределенное значение, как это часто бывает в обработчиках событий, особенно в jQuery, и обратный вызов использует this(или arguments), вы не можете использовать функцию стрелки!
Вариадические функции
Так как функции стрелок не имеют своих собственных arguments, вы не можете просто заменить их функцией стрелок. Однако ES2015 представляет альтернативу использованию arguments: параметр rest .
// old
function sum() {
let args = [].slice.call(arguments);
// ...
}
// new
const sum = (...args) => {
// ...
};
Связанный вопрос:
Другие ресурсы: