Quelles sont les différences (le cas échéant) entre les fonctions de la flèche ES6 et les fonctions liées à la fonction.prototype.lier?
il me semble que, dans ES6, les deux fonctions suivantes sont très presque identique:
function () {
return this;
}.bind(this);
() => {
return this;
};
le résultat final semble le même: les fonctions de flèche produisent un objet de fonction JavaScript avec leur contexte this
lié à la même valeur que le this
où ils sont créés.
évidemment, dans le sens général, Function.prototype.bind
est plus flexible que les fonctions de flèche: il peut lier à des valeurs autres que le local this
, et il peut lier n'importe quelle fonction this
à n'importe quel moment dans le temps, potentiellement longtemps après qu'il soit créé initialement. Cependant, je ne demande pas comment bind
lui-même est différent des fonctions de flèche, je demande comment les fonctions de flèche diffèrent d'appeler immédiatement bind
avec this
.
y a-t-il des différences entre les deux constructions dans ES6?
3 réponses
il n'y a pas de différences (significatives).
C'est un peu prématuré. Il y a trois minuscule différences uniques aux fonctions de flèche.
-
les fonctions de flèche ne peuvent pas être utilisées avec
new
.cela signifie, Bien sûr, qu'ils n'ont pas de propriété
prototype
et ne peuvent pas être utilisés pour créer un objet avec la syntaxe d'inspiration classique.new (() => {}) // TypeError: () => {} is not a constructor
c'est probablement pour le mieux, bien que-la façon
new
fonctionne ne serait pas beaucoup de sens avec des fonctions liées. -
les fonctions de flèche n'ont pas accès à l'objet spécial
arguments
auquel les fonctions JavaScript ordinaires ont accès.(() => arguments)(1, 2, 3) // ReferenceError: arguments is not defined
celui-ci est probablement un peu plus d'un gotcha. Il s'agit probablement de supprimer une des autres bizarreries de JavaScript. l'objet
arguments
est sa propre bête spéciale , et il a un comportement étrange, il n'est donc pas surprenant qu'il ait été lancé.au lieu de cela, ES6 a splats qui peuvent accomplir la même chose sans aucune variables magiques cachés:
((...args) => args)(1, 2, 3) // [1, 2, 3]
-
les fonctions de flèche n'ont pas leur propre
new.target
propriété, ils utilisent lenew.target
de leur fonction de fermeture, si elle exister.cela est compatible avec les autres changements visant à supprimer les valeurs introduites" par magie " pour les fonctions de flèche. Ce changement particulier est particulièrement évident, étant donné que les fonctions de flèche ne peuvent pas être utilisées avec
new
de toute façon, comme mentionné ci-dessus.
sinon, les flèches sont comme des fonctions liées, sémantiquement. Il est possible que les flèches soient plus performantes, puisqu'elles n'ont pas à transporter les bagages supplémentaires. et puisqu'ils n'ont pas besoin d'être convertis à partir de fonctions ordinaires d'abord, mais ils sont comportementaux exactement les mêmes.
il y a quelques différences:
-
les fonctions de flèche ne peuvent pas être construites. Alors que les deux fonctions arrow et les fonctions liées n'ont pas de propriété
.prototype
, les premières font exception lorsqu'elles sont appelées avecnew
tandis que les secondes ignorent simplement la valeur liée et appellent leur fonction cible comme un constructeur (avec les arguments liés partiellement appliqués, cependant) sur la nouvelle instance.function F() {} var f = () => {}, boundF = F.bind({}); console.log(new boundF(), new boundF instanceof F) // {}, true console.log(new f) // TypeError
-
les fonctions de flèche ont aussi des fonctions lexicales
arguments
,new.target
etsuper
(pas seulement lexicalthis
). Un appel à une fonction Flèche n'initialise aucune de celles-ci, elles sont simplement héritées de la fonction dans laquelle la fonction flèche a été définie. Dans une fonction liée, ils se réfèrent juste aux valeurs respectives de la fonction cible. -
les fonctions de flèche ne lient pas réellement un
this
valeur. Plutôt, ils n'en ont pas, et lorsque vous utilisezthis
il est regardé comme un nom de variable dans la portée lexicale. Cela vous permet de définir une fonction de flèche alors quethis
n'est pas encore disponible:class X extends Object { constructor() { var f = () => this, // works boundF = function(){ return this; }.bind(this); // ^^^^ ReferenceError super(); // initialises `this` console.log(f(), f() == this); // {}, true } } new X;
-
les fonctions de flèche ne peuvent pas être des fonctions de générateur (bien qu'elles puissent retourner des générateurs). Vous pouvez utiliser
.bind()
sur une fonction de générateur, mais il n'y a aucun moyen d'exprimer cela en utilisant une fonction de flèche.
Voici une différence plus subtile:
Les fonctions de flèchepeuvent retourner une valeur sans utiliser le mot-clé 'return', en omettant les accolades {} suivant le => immédiatement.
var f=x=>x; console.log(f(3)); // 3
var g=x=>{x}; console.log(g(3)); // undefined
var h=function(x){x}; console.log(h(3)); // undefined
var i=x=>{a:1}; console.log(i(3)); // undefined
var j=x=>({a:1}); console.log(j(3)); // {a:1}