Quelle est la signification de «=>» (une flèche formée de égaux et supérieurs à) en JavaScript?

444

Je sais que l' >=opérateur signifie plus ou égal à, mais j'ai vu =>dans du code source. Quelle est la signification de cet opérateur?

Voici le code:

promiseTargetFile(fpParams, aSkipPrompt, relatedURI).then(aDialogAccepted => {
    if (!aDialogAccepted)
        return;

    saveAsType = fpParams.saveAsType;
    file = fpParams.file;

    continueSave();
}).then(null, Components.utils.reportError);
rpgs_player
la source
5
Voir ce lien sur les fonctions fléchées .
Mistalis

Réponses:

546

Ce que c'est

Il s'agit d'une fonction de flèche. Les fonctions fléchées sont une syntaxe courte, introduite par ECMAscript 6, qui peut être utilisée de la même manière que vous utiliseriez des expressions de fonction. En d'autres termes, vous pouvez souvent les utiliser à la place d'expressions comme function (foo) {...}. Mais ils ont des différences importantes. Par exemple, ils ne lient pas leurs propres valeurs de this(voir ci-dessous pour la discussion).

Les fonctions fléchées font partie de la spécification ECMAscript 6. Ils ne sont pas encore pris en charge dans tous les navigateurs, mais ils sont partiellement ou entièrement pris en charge dans Node v. 4.0+ et dans la plupart des navigateurs modernes utilisés à partir de 2018 (j'ai inclus une liste partielle des navigateurs pris en charge ci-dessous).

Vous pouvez en lire plus dans la documentation de Mozilla sur les fonctions fléchées .

De la documentation Mozilla:

Une expression de la fonction de défilement (également connu sous le nom de matières grasses fonction de la flèche) a une syntaxe plus courte par rapport aux expressions de fonction et se lie lexicalement la thisvaleur (ne se lie pas son propre this, arguments, super, ou new.target). Les fonctions fléchées sont toujours anonymes. Ces expressions de fonction conviennent mieux aux fonctions non-méthode et ne peuvent pas être utilisées comme constructeurs.

Remarque sur le thisfonctionnement des fonctions fléchées

L'une des fonctionnalités les plus pratiques d'une fonction de flèche est enterrée dans le texte ci-dessus:

Une fonction flèche ... lie lexicalement la thisvaleur (ne lie pas la sienne this...)

En termes plus simples, cela signifie que la fonction flèche conserve la thisvaleur de son contexte et n'a pas la sienne this. Une fonction traditionnelle peut lier sa propre thisvaleur, selon la façon dont elle est définie et appelée. Cela peut nécessiter beaucoup de gymnastique comme self = this;, etc., pour accéder ou manipuler thisd'une fonction à l'intérieur d'une autre fonction. Pour plus d'informations sur ce sujet, consultez les explications et les exemples dans la documentation de Mozilla .

Exemple de code

Exemple (également dans les documents):

var a = [
  "We're up all night 'til the sun",
  "We're up all night to get some",
  "We're up all night for good fun",
  "We're up all night to get lucky"
];

// These two assignments are equivalent:

// Old-school:
var a2 = a.map(function(s){ return s.length });

// ECMAscript 6 using arrow functions
var a3 = a.map( s => s.length );

// both a2 and a3 will be equal to [31, 30, 31, 31]

Remarques sur la compatibilité

Vous pouvez utiliser les fonctions fléchées dans Node, mais la prise en charge du navigateur est inégale.

La prise en charge par le navigateur de cette fonctionnalité s'est beaucoup améliorée, mais elle n'est pas encore assez répandue pour la plupart des utilisations basées sur le navigateur. Depuis le 12 décembre 2017, il est pris en charge dans les versions actuelles de:

  • Chrome (v. 45+)
  • Firefox (v. 22+)
  • Edge (v.12+)
  • Opera (v. 32+)
  • Navigateur Android (v. 47+)
  • Opera Mobile (v. 33+)
  • Chrome pour Android (v. 47+)
  • Firefox pour Android (v. 44+)
  • Safari (version 10+)
  • iOS Safari (v. 10.2+)
  • Samsung Internet (v. 5+)
  • Navigateur Baidu (v. 7.12+)

Non pris en charge dans:

  • IE (par v.11)
  • Opera Mini (jusqu'à v. 8.0)
  • Navigateur Blackberry (via v. 10)
  • IE Mobile (via v. 11)
  • Navigateur UC pour Android (jusqu'à la version 11.4)
  • QQ (jusqu'à v. 1.2)

Vous pouvez trouver plus d'informations (et plus à jour) sur CanIUse.com (sans affiliation).

élixénide
la source
3
TypeScript semble également le prendre en charge.
mtyson
1
On dirait que c'est une expression lambda, oui?
Addem
1
Je voulais mentionner en termes de compatibilité du navigateur que j'utilise les fonctions fléchées ES6 / ES7 et d'autres fonctionnalités non compatibles avec IE11 en natif mais j'utilise Gulp ou Webpack avec Babel pour transpiler ES6 vers ES5 afin que cela fonctionne dans IE11. Donc, si vous avez besoin du support IE11 et que cela ne vous dérange pas de configurer Babel, allez-y.
mbokil
76

C'est ce qu'on appelle une fonction de flèche, qui fait partie de la spécification ECMAScript 2015 ...

var foo = ['a', 'ab', 'abc'];

var bar = foo.map(f => f.length);

console.log(bar); // 1,2,3

Syntaxe plus courte que la précédente:

// < ES6:
var foo = ['a', 'ab', 'abc'];

var bar = foo.map(function(f) {
  return f.length;
});
console.log(bar); // 1,2,3

DEMO

L'autre chose géniale est lexicale this ... Habituellement, vous feriez quelque chose comme:

function Foo() {
  this.name = name;
  this.count = 0;
  this.startCounting();
}

Foo.prototype.startCounting = function() {
  var self = this;
  setInterval(function() {
    // this is the Window, not Foo {}, as you might expect
    console.log(this); // [object Window]
    // that's why we reassign this to self before setInterval()
    console.log(self.count);
    self.count++;
  }, 1000)
}

new Foo();

Mais cela pourrait être réécrit avec la flèche comme ceci:

function Foo() {
  this.name = name;
  this.count = 0;
  this.startCounting();
}

Foo.prototype.startCounting = function() {
  setInterval(() => {
    console.log(this); // [object Object]
    console.log(this.count); // 1, 2, 3
    this.count++;
  }, 1000)
}

new Foo();

DEMO

MDN
Plus d'informations sur la syntaxe

Pour en savoir plus, voici une assez bonne réponse pour savoir quand utiliser les fonctions fléchées.

brbcoding
la source
Il serait bon de mettre à jour les démos pour utiliser esfiddle.net car es6fiddle.net n'est plus opérationnel
Wavesailor
25

Ce serait "l'expression de la fonction flèche" introduite dans ECMAScript 6.

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/arrow_functions

À des fins historiques (si la page wiki change plus tard), c'est:

Une expression de fonction flèche a une syntaxe plus courte que les expressions de fonction et lie lexicalement cette valeur. Les fonctions fléchées sont toujours anonymes.

Kyle Falconer
la source
1
voulez-vous inclure suffisamment d'informations pour que la plupart des lecteurs n'aient pas à explorer?
djechlin
2
Le wiki auquel j'ai lié décrit très succinctement ce que c'est: "Une expression de fonction de flèche a une syntaxe plus courte par rapport aux expressions de fonction et lie lexicalement cette valeur. Les fonctions de flèche sont toujours anonymes."
Kyle Falconer
1
L'ajout de cette citation ici aidera vraiment votre réponse.
Hanky ​​Panky
22

Ce sont des fonctions fléchées

Aussi connu sous le nom de Fat Arrow Functions . Ils sont un moyen propre et simple d'écrire des expressions de fonction, par exemple function() {}.

Les fonctions fléchées peuvent supprimer le besoin de function, returnet {}lors de la définition des fonctions. Ce sont des lignes simples, similaires aux expressions Lambda en Java ou en Python.

Exemple sans paramètres

const queue = ['Dave', 'Sarah', 'Sharon'];
const nextCustomer = () => queue[0];

console.log(nextCustomer()); // 'Dave'

Si plusieurs instructions doivent être faites dans la même fonction de flèche, vous devez encapsuler, dans cet exemple, queue[0]entre crochets {}. Dans ce cas, la déclaration de retour ne peut pas être omise.

Exemple avec 1 paramètre

const queue = ['Dave', 'Sarah', 'Sharon'];
const addCustomer = name => {
  queue.push(name);
};

addCustomer('Toby');

console.log(queue); // ['Dave', 'Sarah', 'Sharon', 'Toby']

Vous pouvez omettre {}de ce qui précède.

Lorsqu'il n'y a qu'un seul paramètre, les crochets ()autour du paramètre peuvent être omis.

Exemple avec plusieurs paramètres

const addNumbers = (x, y) => x + y

console.log(addNumbers(1, 5)); // 6

Un exemple utile

const fruits = [
    {name: 'Apple', price: 2},
    {name: 'Bananna', price: 3},
    {name: 'Pear', price: 1}
];

Si nous voulions obtenir le prix de chaque fruit dans une seule gamme, dans ES5, nous pouvions faire:

fruits.map(function(fruit) {
    return fruit.price;
}); // [2, 3, 1]

Dans ES6 avec les nouvelles fonctions fléchées, nous pouvons rendre cela plus concis:

fruits.map(fruit => fruit.price); // [2, 3, 1]

Des informations supplémentaires sur les fonctions fléchées sont disponibles ici .

Compatibilité du navigateur

  • IE: pas encore pris en charge
  • Edge: 12+ (toutes les versions)
  • Firefox: 22+
  • Chrome: 45+
  • Safari: 10+
  • iOS Safari: 10.2+
  • Navigateur Android: 56+

Des informations supplémentaires à jour peuvent être trouvées sur la compatibilité du navigateur ici

Toby Mellor
la source
21

juste pour ajouter un autre exemple de ce qu'un lambda peut faire sans utiliser map:

a = 10
b = 2

var mixed = (a,b) => a * b; 
// OR
var mixed = (a,b) => { (any logic); return a * b };

console.log(mixed(a,b)) 
// 20
Bart Calixto
la source
13

Comme d'autres l'ont dit, c'est une nouvelle syntaxe pour créer des fonctions.

Cependant, ce type de fonctions diffère des fonctions normales:

  • Ils lient la thisvaleur. Comme expliqué par la spécification ,

    Un ArrowFunction pour ne définit pas des liaisons locales arguments, super, thisou new.target. Toute référence à arguments, super, thisou new.targetdans un ArrowFunction doit se résoudre à une fixation dans un environnement qui entoure lexicalement. Il s'agit généralement de l'environnement fonctionnel d'une fonction immédiatement englobante.

    Même si un ArrowFunction peut contenir des références à super, l'objet fonction créé à l'étape 4 n'est pas transformé en une méthode en exécutant MakeMethod . Une fonction ArrowFunction qui fait référence super est toujours contenue dans une fonction non ArrowFunction et l'état nécessaire à implémenter superest accessible via l' étendue capturée par l'objet fonction de la fonction ArrowFunction .

  • Ce sont des non constructeurs.

    Cela signifie qu'ils n'ont pas de méthode interne [[Construct]] et ne peuvent donc pas être instanciés, par exemple

    var f = a => a;
    f(123);  // 123
    new f(); // TypeError: f is not a constructor
Oriol
la source
8

Je l' ai lu, c'est un symbole de Arrow FunctionsdansES6

cette

var a2 = a.map(function(s){ return s.length });

en utilisant Arrow Functionpeut être écrit comme

var a3 = a.map( s => s.length );

Documents MDN

Mritunjay
la source
6

Ajout d'un exemple CRUD simple avec Arrowfunction

 //Arrow Function
 var customers   = [
   {
     name: 'Dave',
     contact:'9192631770'
   },
   {
     name: 'Sarah',
     contact:'9192631770'
   },
   {
     name: 'Akhil',
     contact:'9928462656' 
   }],

// No Param READ
 getFirstCustomer = () => { 
   console.log(this);
   return customers[0];
 };
  console.log("First Customer "+JSON.stringify(getFirstCustomer())); // 'Dave' 

   //1 Param SEARCH
  getNthCustomer = index=>{
    if( index>customers.length)
    {
     return  "No such thing";
   }
   else{
       return customers[index];
     } 
  };
  console.log("Nth Customer is " +JSON.stringify(getNthCustomer(1))); 

   //2params ADD
  addCustomer = (name, contact)=> customers.push({
     'name': name,
     'contact':contact
    });
  addCustomer('Hitesh','8888813275');
  console.log("Added Customer "+JSON.stringify(customers)); 

  //2 param UPDATE
  updateCustomerName = (index, newName)=>{customers[index].name= newName};
  updateCustomerName(customers.length-1,"HiteshSahu");
  console.log("Updated Customer "+JSON.stringify(customers));

  //1 param DELETE
  removeCustomer = (customerToRemove) => customers.pop(customerToRemove);
  removeCustomer(getFirstCustomer());
  console.log("Removed Customer "+JSON.stringify(customers)); 
Hitesh Sahu
la source
4

Insatisfait des autres réponses. La réponse la plus votée en date du 2019/3/13 est en fait fausse.

La version abrégée de ce qui =>signifie est un raccourci pour écrire une fonction ET pour la lier au courantthis

const foo = a => a * 2;

Est effectivement un raccourci pour

const foo = function(a) { return a * 2; }.bind(this);

Vous pouvez voir toutes les choses qui se sont raccourcies. Nous n'avions pas besoin function, ni returnni .bind(this)ni ni même d'accolades ou de parenthèses

Un exemple légèrement plus long de fonction de flèche peut être

const foo = (width, height) => {
  const area = width * height;
  return area;
};

Montrer que si nous voulons plusieurs arguments pour la fonction, nous avons besoin de parenthèses et si nous voulons écrire plus d'une seule expression, nous avons besoin d'accolades et d'un explicite return.

Il est important de comprendre la .bindpartie et c'est un gros sujet. Cela a à voir avec ce que thissignifie en JavaScript.

TOUTES les fonctions ont un paramètre implicite appelé this. La façon dont thisest définie lors de l'appel d'une fonction dépend de la façon dont cette fonction est appelée.

Prendre

function foo() { console.log(this); }

Si vous l'appelez normalement

function foo() { console.log(this); }
foo();

this sera l'objet global.

Si vous êtes en mode strict

`use strict`;
function foo() { console.log(this); }
foo();

// or

function foo() {
   `use strict`;
   console.log(this);
 }
foo();

Ce sera undefined

Vous pouvez définir thisdirectement en utilisant callouapply

function foo(msg) { console.log(msg, this); }

const obj1 = {abc: 123}
const obj2 = {def: 456}

foo.call(obj1, 'hello');  // prints Hello {abc: 123}
foo.apply(obj2, ['hi']);  // prints Hi {def: 456}

Vous pouvez également définir thisimplicitement à l'aide de l'opérateur point.

function foo(msg) { console.log(msg, this); }
const obj = {
   abc: 123,
   bar: foo,
}
obj.bar('Hola');  // prints Hola {abc:123, bar: f}

Un problème survient lorsque vous souhaitez utiliser une fonction comme rappel ou écouteur. Vous créez une classe et souhaitez affecter une fonction comme rappel qui accède à une instance de la classe.

class ShowName {
  constructor(name, elem) {
    this.name = name;
    elem.addEventListener('click', function() {
       console.log(this.name);  // won't work
    }); 
  }
}

Le code ci-dessus ne fonctionnera pas car lorsque l'élément déclenche l'événement et appelle la fonction, la thisvaleur ne sera pas l'instance de la classe.

Une façon courante de résoudre ce problème consiste à utiliser .bind

class ShowName {
  constructor(name, elem) {
    this.name = name;
    elem.addEventListener('click', function() {
       console.log(this.name); 
    }.bind(this); // <=========== ADDED! ===========
  }
}

Parce que la syntaxe des flèches fait la même chose que nous pouvons écrire

class ShowName {
  constructor(name, elem) {
    this.name = name;
    elem.addEventListener('click',() => {
       console.log(this.name); 
    });
  }
}

bindfait effectivement une nouvelle fonction . Si cela bindn'existait pas, vous pourriez en fait créer le vôtre comme ceci

function bind(funcitonToBind, valueToUseForThis) {
  return function(...args) {
    functionToBind.call(valueToUseForThis, ...args);
  };
}

Dans les anciens JavaScript sans l'opérateur de propagation, il serait

function bind(funcitonToBind, valueToUseForThis) {
  return function() {
    functionToBind.apply(valueToUseForThis, arguments);
  };
}

La compréhension de ce code nécessite une compréhension des fermetures mais la version courte est bindune nouvelle fonction qui appelle toujours la fonction d'origine avec la thisvaleur qui lui était liée. fonction de flèche fait la même chose car ils sont un raccourci pourbind(this)

gman
la source
2

Comme toutes les autres réponses l'ont déjà dit, cela fait partie de la syntaxe de la fonction de flèche ES2015. Plus précisément, ce n'est pas un opérateur, il est un ponctueur jeton qui sépare les paramètres du corps: ArrowFunction : ArrowParameters => ConciseBody. Par exemple (params) => { /* body */ }.

JMM
la source
1

ES6 Fonctions fléchées:

En javascript, le =>est le symbole d'une expression de fonction de flèche. Une expression de fonction flèche n'a pas sa propre thisliaison et ne peut donc pas être utilisée comme fonction constructeur. par exemple:

var words = 'hi from outside object';

let obj = {
  words: 'hi from inside object',
  talk1: () => {console.log(this.words)},
  talk2: function () {console.log(this.words)}
}

obj.talk1();  // doesn't have its own this binding, this === window
obj.talk2();  // does have its own this binding, this is obj

Règles d'utilisation des fonctions fléchées:

  • S'il y a exactement un argument, vous pouvez omettre les parenthèses de l'argument.
  • Si vous retournez une expression et faites cela sur la même ligne, vous pouvez omettre {}l' returninstruction et

Par exemple:

let times2 = val => val * 2;  
// It is on the same line and returns an expression therefore the {} are ommited and the expression returns implictly
// there also is only one argument, therefore the parentheses around the argument are omitted

console.log(times2(3));

Willem van der Veen
la source
1

Les fonctions fléchées désignées par le symbole (=>) vous aident à créer des fonctions et des méthodes anonymes. Cela conduit à une syntaxe plus courte. Par exemple, ci-dessous se trouve une simple fonction «Ajouter» qui renvoie l'addition de deux nombres.

function Add(num1 , num2 ){
return num1 + num2;
}

La fonction ci-dessus devient plus courte en utilisant la syntaxe «Flèche» comme indiqué ci-dessous.

entrez la description de l'image ici

Le code ci-dessus a deux parties comme indiqué dans le diagramme ci-dessus: -

Entrée: - Cette section spécifie les paramètres d'entrée de la fonction anonyme.

Logique: - Cette section vient après le symbole «=>». Cette section présente la logique de la fonction réelle.

De nombreux développeurs pensent que la fonction flèche rend votre syntaxe plus courte, plus simple et rend ainsi votre code lisible.

Si vous croyez à la phrase ci-dessus, laissez-moi vous assurer que c'est un mythe. Si vous pensez un instant qu'une fonction correctement écrite avec un nom est beaucoup plus lisible que les fonctions cryptiques créées sur une seule ligne à l'aide d'un symbole de flèche.

L'utilisation principale de la fonction flèche est de s'assurer que le code s'exécute dans le contexte des appelants.

Voir le code ci-dessous dans lequel une variable globale "context" est définie, cette variable globale est accessible à l'intérieur d'une fonction "SomeOtherMethod" qui est appelée à partir d'une autre méthode "SomeMethod".

Cette "SomeMethod" a une variable "contextuelle" locale. Maintenant, parce que "SomeOtherMethod" est appelé depuis "" SomeMethod ", nous nous attendons à ce qu'il affiche le" contexte local ", mais il affiche le" contexte global ".

var context = global context”;

function SomeOtherMethod(){
alert(this.context);
}

function SomeMethod(){
this.context = local context”;
SomeOtherMethod();
}

var instance = new SomeMethod();

Mais si vous remplacez l'appel en utilisant la fonction Flèche, il affichera le "contexte local".

var context = "global context";

    function SomeMethod(){
        this.context = "local context";
        SomeOtherMethod = () => {
            alert(this.context);
        }
        SomeOtherMethod();
    }
    var instance = new SomeMethod();

Je vous encourage à lire ce lien ( fonction Flèche en JavaScript ) qui explique tous les scénarios du contexte javascript et dans quels scénarios le contexte des appelants n'est pas respecté.

Vous pouvez également voir la démonstration de la fonction Flèche avec javascript dans cette vidéo youtube qui illustre pratiquement le terme Contexte.

Shivprasad Koirala
la source
0

Comme d'autres l'ont dit, les fonctions régulières (traditionnelles) sont utilisées à thispartir de l'objet qui a appelé la fonction (par exemple un bouton sur lequel vous avez cliqué) . Au lieu de cela, les fonctions fléchées utilisentthis partir de l'objet qui définit la fonction.

Considérez deux fonctions presque identiques:

regular = function() {
  ' Identical Part Here;
}


arrow = () => {
  ' Identical Part Here;
}

L'extrait ci-dessous montre la différence fondamentale entre ce que thisreprésente pour chaque fonction. La fonction régulière sort [object HTMLButtonElement]alors que la fonction flèche sort [object Window].

<html>
 <button id="btn1">Regular: `this` comes from "this button"</button>
 <br><br>
 <button id="btn2">Arrow: `this` comes from object that defines the function</button>
 <p id="res"/>

 <script>
  regular = function() {
    document.getElementById("res").innerHTML = this;
  }

  arrow = () => {
    document.getElementById("res").innerHTML = this;
  }

  document.getElementById("btn1").addEventListener("click", regular);
  document.getElementById("btn2").addEventListener("click", arrow);
 </script>
</html>

SlowLearner
la source