Les fonctions de flèche dans ES2015 fournissent une syntaxe plus concise.
Exemples:
Fonction constructeur
function User(name) {
this.name = name;
}
// vs
const User = name => {
this.name = name;
};
Méthodes de prototype
User.prototype.getName = function() {
return this.name;
};
// vs
User.prototype.getName = () => this.name;
Méthodes d'objet (littéral)
const obj = {
getName: function() {
// ...
}
};
// vs
const obj = {
getName: () => {
// ...
}
};
Rappels
setTimeout(function() {
// ...
}, 500);
// vs
setTimeout(() => {
// ...
}, 500);
Fonctions variadiques
function sum() {
let args = [].slice.call(arguments);
// ...
}
// vs
const sum = (...args) => {
// ...
};
tl; dr: Non! Les fonctions de flèche et les déclarations/expressions de fonction sont pas équivalent et ne peut pas être remplacé aveuglément.
Si la fonction que vous voulez remplacer ne pas utilisez this
, arguments
et n'est pas appelée avec new
, alors Oui.
Comme souvent: cela dépend . Les fonctions des flèches ont un comportement différent de celui des déclarations/expressions de fonctions, examinons donc d'abord les différences:
1. Lexical this
et arguments
Les fonctions fléchées n'ont pas leur propre liaison this
ou arguments
. Au lieu de cela, ces identificateurs sont résolus dans la portée lexicale comme toute autre variable. Cela signifie qu'à l'intérieur d'une fonction de flèche, this
et arguments
font référence aux valeurs de this
et arguments
dans l'environnement, la fonction de flèche est définie dans (c'est-à-dire "en dehors" de la fonction de flèche):
// 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
Dans le cas de l'expression de fonction, this
fait référence à l'objet créé à l'intérieur de createObject
. Dans le cas de la fonction de flèche, this
fait référence à this
de createObject
lui-même.
Cela rend les fonctions de flèche utiles si vous devez accéder à la this
de l’environnement actuel:
// currently common pattern
var that = this;
getData(function(data) {
that.data = data;
});
// better alternative with arrow functions
getData(data => {
this.data = data;
});
Notez que cela signifie également que n'est pas possible de définir la fonction this
d'une fonction de flèche avec .bind
ou .call
.
Si vous n'êtes pas très familier avec this
, envisagez de lire
2. Les fonctions de flèche ne peuvent pas être appelées avec new
ES2015 distingue les fonctions qui sont appellent et les fonctions qui sont construct . Si une fonction est constructible, elle peut être appelée avec new
, c'est-à-dire new User()
. Si une fonction est appelable, elle peut être appelée sans new
(c'est-à-dire un appel de fonction normal).
Les fonctions créées par les déclarations/expressions de fonction sont à la fois constructibles et appelables.
Les fonctions (et méthodes) des flèches ne peuvent être appelées. Les constructeurs class
ne sont constructibles que.
Si vous essayez d'appeler une fonction non appelable ou de construire une fonction non constructible, vous obtiendrez une erreur d'exécution.
Sachant cela, nous pouvons affirmer ce qui suit.
Remplaçable:
this
ou arguments
..bind(this)
non remplaçable:
this
)arguments
(voir ci-dessous))Regardons cela de plus près en utilisant vos exemples:
Fonction constructeur
Cela ne fonctionnera pas car les fonctions de flèche ne peuvent pas être appelées avec new
. Continuez à utiliser une déclaration/expression de fonction ou utilisez class
.
Méthodes prototypes
Probablement pas, car les méthodes prototypes utilisent généralement this
pour accéder à l'instance. S'ils n'utilisent pas this
, vous pouvez le remplacer. Cependant, si vous vous souciez principalement de la syntaxe concise, utilisez class
avec sa syntaxe de méthode concise:
class User {
constructor(name) {
this.name = name;
}
getName() {
return this.name;
}
}
Méthodes objet
De même pour les méthodes dans un objet littéral. Si la méthode veut référencer l'objet lui-même via this
, continuez à utiliser des expressions de fonction ou utilisez la nouvelle syntaxe de la méthode:
const obj = {
getName() {
// ...
},
};
Rappels
Ça dépend. Vous devez absolument le remplacer si vous aliasez le this
extérieur ou si vous utilisez .bind(this)
:
// old
setTimeout(function() {
// ...
}.bind(this), 500);
// new
setTimeout(() => {
// ...
}, 500);
Mais: Si le code qui appelle le rappel affecte explicitement this
à une valeur spécifique, comme c'est souvent le cas avec les gestionnaires d'événements, en particulier avec jQuery, et le rappel utilise this
(ou arguments
), vous ne pouvez pas utiliser une fonction de flèche!
Fonctions variadiques
Les fonctions de flèches n'ayant pas leur propre arguments
, vous ne pouvez pas les remplacer simplement par une fonction de flèches. Cependant, ES2015 introduit une alternative à l’utilisation de arguments
: le paramètre de repos .
// old
function sum() {
let args = [].slice.call(arguments);
// ...
}
// new
const sum = (...args) => {
// ...
};
Question connexe:
Autres ressources:
La variable this
est très différente timesCalled
ne s'incrémente que de 1 à chaque appel du bouton. Ce qui répond à ma question personnelle:
.click( () => { } )
et
.click(function() { })
les deux créent le même nombre de fonctions lorsqu'elles sont utilisées dans une boucle que vous pouvez voir à partir du nombre de Guid dans le Plnkr.