tl; dr: Nie! Funkcje strzałek oraz deklaracje / wyrażenia funkcji nie są równoważne i nie można ich zastępować na ślepo.
Jeśli funkcja chcesz zastąpić ma nie używać this
, arguments
a nie jest wywołana new
, to tak.
Jak często: to zależy . Funkcje strzałek mają inne zachowanie niż deklaracje / wyrażenia funkcji, więc najpierw spójrzmy na różnice:
1. Leksykalny this
iarguments
Funkcje strzałek nie mają własnych this
ani arguments
wiążących. Zamiast tego identyfikatory te są rozwiązywane w zakresie leksykalnym, jak każda inna zmienna. Oznacza to, że wewnątrz funkcji strzałki, this
i arguments
odnoszą się do wartości this
i arguments
w środowisku funkcja strzałka jest zdefiniowany w (czyli „na zewnątrz”, funkcja strzałka):
// 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
W przypadku wyrażenia funkcyjnego this
odnosi się do obiektu, który został utworzony wewnątrz createObject
. W przypadku funkcji strzałki, this
odnosi się this
od createObject
siebie.
To sprawia, że funkcje strzałek są przydatne, jeśli chcesz uzyskać dostęp this
do bieżącego środowiska:
// currently common pattern
var that = this;
getData(function(data) {
that.data = data;
});
// better alternative with arrow functions
getData(data => {
this.data = data;
});
Zauważ, że oznacza to również, że nie można ustawić funkcji strzałek za this
pomocą .bind
lub .call
.
Jeśli nie znasz się dobrze this
, rozważ lekturę
2. Nie można wywoływać funkcji strzałek za pomocą new
ES2015 rozróżnia funkcje, które można wywoływać, i funkcje, które można konstruować . Jeśli funkcja jest konstruowalna, można ją wywołać za pomocą new
np new User()
. Jeśli funkcja jest wywoływalna, można ją wywołać bez new
(tzn. Normalne wywołanie funkcji).
Funkcje utworzone za pomocą deklaracji / wyrażeń funkcji można konstruować i wywoływać.
Funkcje strzałek (i metody) można wywoływać tylko.
class
konstruktory są tylko do zbudowania.
Jeśli próbujesz wywołać funkcję, której nie można wywołać, lub zbudować funkcję, której nie można zbudować, pojawi się błąd czasu wykonywania.
Wiedząc o tym, możemy stwierdzić, co następuje.
Wymienny:
- Funkcje, które nie używają
this
lub arguments
.
- Funkcje używane z
.bind(this)
Nie wymienny:
- Funkcje konstruktora
- Funkcja / metody dodane do prototypu (ponieważ zwykle używają
this
)
- Funkcje Variadic (jeśli używają
arguments
(patrz poniżej))
Przyjrzyjmy się temu na twoich przykładach:
Funkcja konstruktora
To nie zadziała, ponieważ nie można wywoływać funkcji strzałek new
. Nadal używaj deklaracji / wyrażenia funkcji lub użyj class
.
Metody prototypowe
Najprawdopodobniej nie, ponieważ this
do uzyskania dostępu do instancji zwykle używają metod prototypowych . Jeśli nie używają this
, możesz je wymienić. Jeśli jednak zależy ci przede wszystkim na zwięzłej składni, użyj class
jej zwięzłej metody:
class User {
constructor(name) {
this.name = name;
}
getName() {
return this.name;
}
}
Metody obiektowe
Podobnie w przypadku metod w dosłowności obiektu. Jeśli metoda chce odwoływać się do samego obiektu this
, nadal używaj wyrażeń funkcyjnych lub użyj nowej składni metody:
const obj = {
getName() {
// ...
},
};
Callbacki
To zależy. Zdecydowanie powinieneś go wymienić, jeśli korzystasz z aliasu zewnętrznego this
lub używasz .bind(this)
:
// old
setTimeout(function() {
// ...
}.bind(this), 500);
// new
setTimeout(() => {
// ...
}, 500);
Ale: Jeśli kod wywołujący wywołanie zwrotne jawnie ustawia this
określoną wartość, jak to często ma miejsce w przypadku programów obsługi zdarzeń, szczególnie w jQuery, a wywołanie zwrotne używa this
(lub arguments
), nie można użyć funkcji strzałki!
Funkcje Variadic
Ponieważ funkcje strzałek nie mają własnych arguments
, nie można po prostu zastąpić ich funkcją strzałki. Jednak ES2015 wprowadza alternatywę dla używania arguments
: parametru rest .
// old
function sum() {
let args = [].slice.call(arguments);
// ...
}
// new
const sum = (...args) => {
// ...
};
Powiązane pytanie:
Dalsze zasoby: