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?

40
demandé sur Alexis King 2015-09-12 07:17:20

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.

  1. 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.

  2. 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]
    
  3. les fonctions de flèche n'ont pas leur propre new.target propriété, ils utilisent le new.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.

32
répondu Alexis King 2017-05-23 12:32:10

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 avec new 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 et super (pas seulement lexical this ). 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 utilisez this 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 que this 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.

28
répondu Bergi 2017-01-25 13:26:50

Voici une différence plus subtile:

Les fonctions de flèche

peuvent 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}
3
répondu Chong Lip Phang 2018-05-17 15:52:59