ДЛ: Нет! Функции стрелок и объявления / выражения функций не эквивалентны и не могут быть заменены вслепую.
Если функция, которую вы хотите заменить, не использует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) => {
// ...
};
Связанный вопрос:
Другие ресурсы: