Qual è il significato di "=>" (una freccia formata da uguale e maggiore di) in JavaScript?


444

So che l' >=operatore significa più o uguale a, ma ho visto =>in qualche codice sorgente. Qual è il significato di quell'operatore?

Ecco il codice:

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

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

    continueSave();
}).then(null, Components.utils.reportError);

5
Vedi questo link sulle funzioni delle frecce .
Mistalis,

Risposte:


547

Cos'è

Questa è una funzione freccia. Le funzioni freccia sono una sintassi breve, introdotta da ECMAscript 6, che può essere utilizzata in modo simile al modo in cui useresti le espressioni di funzione. In altre parole, puoi spesso usarli al posto di espressioni come function (foo) {...}. Ma hanno alcune differenze importanti. Ad esempio, non vincolano i propri valori di this(vedi sotto per la discussione).

Le funzioni freccia fanno parte delle specifiche ECMAscript 6. Non sono ancora supportati in tutti i browser, ma sono parzialmente o completamente supportati in Nodo v. 4.0+ e nella maggior parte dei browser moderni in uso dal 2018. (Di seguito ho incluso un elenco parziale di browser di supporto).

Puoi leggere di più nella documentazione di Mozilla sulle funzioni delle frecce .

Dalla documentazione di Mozilla:

Un'espressione funzione di freccia (noto anche come funzione di freccia grasso) ha una sintassi più breve rispetto a espressioni di funzione e lessicalmente si lega il thisvalore (non vincola la propria this, arguments, super, o new.target). Le funzioni freccia sono sempre anonime. Queste espressioni di funzioni sono più adatte per funzioni non di metodo e non possono essere utilizzate come costruttori.

Una nota su come thisfunziona nelle funzioni freccia

Una delle funzioni più utili di una funzione freccia è sepolta nel testo sopra:

Una funzione freccia ... associa in modo lessicale il thisvalore (non associa il proprio this...)

Ciò significa in parole povere che la funzione freccia conserva il thisvalore dal suo contesto e non ha il suo this. Una funzione tradizionale può associare il proprio thisvalore, a seconda di come viene definita e chiamata. Ciò può richiedere molta ginnastica come self = this;, ecc., Per accedere o manipolare thisda una funzione all'interno di un'altra funzione. Per ulteriori informazioni su questo argomento, consultare la spiegazione e gli esempi nella documentazione di Mozilla .

Codice di esempio

Esempio (anche dai documenti):

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]

Note sulla compatibilità

È possibile utilizzare le funzioni freccia in Nodo, ma il supporto del browser è imprevedibile.

Il supporto del browser per questa funzionalità è leggermente migliorato, ma non è ancora abbastanza diffuso per la maggior parte degli utilizzi basati su browser. A partire dal 12 dicembre 2017, è supportato nelle versioni correnti di:

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

Non supportato in:

  • IE (attraverso la v. 11)
  • Opera Mini (attraverso la v. 8.0)
  • Blackberry Browser (attraverso la v. 10)
  • IE Mobile (fino alla v. 11)
  • UC Browser per Android (tramite v. 11.4)
  • QQ (tramite v. 1.2)

Puoi trovare più (e più attuali) informazioni su CanIUse.com (nessuna affiliazione).


3
Anche TypeScript sembra supportarlo.
mtyson,

1
Sembra che questa sia un'espressione lambda, sì?
Addem

1
Volevo menzionare in termini di compatibilità del browser, utilizzo le funzioni freccia ES6 / ES7 e altre funzionalità non compatibili con IE11 in modo nativo, ma utilizzo Gulp o Webpack insieme a Babel per trasferire ES6 su ES5 in modo che funzioni in IE11. Quindi, se hai bisogno del supporto di IE11 e non ti dispiace configurare Babel, allora provaci.
mbokil,

76

Questa è conosciuta come una funzione freccia, parte delle specifiche ECMAScript 2015 ...

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

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

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

Sintassi più breve della precedente:

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

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

DEMO

L'altra cosa fantastica è lessicale this ... Di solito, faresti qualcosa del tipo:

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();

Ma questo potrebbe essere riscritto con la freccia in questo modo:

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
Altre informazioni sulla sintassi

Per di più, ecco una risposta abbastanza buona per quando usare le funzioni freccia.


Sarebbe bello aggiornare le demo per usare esfiddle.net poiché es6fiddle.net non è più operativo
Wavesailor

25

Questa sarebbe l'espressione "funzione della freccia" introdotta in ECMAScript 6.

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

Per scopi storici (se la pagina wiki cambia in seguito), è:

Un'espressione di funzione freccia ha una sintassi più breve rispetto alle espressioni di funzione e associa lessicamente questo valore. Le funzioni freccia sono sempre anonime.


1
ti dispiace includere informazioni sufficienti in modo che la maggior parte dei lettori non debba eseguire il drill down?
Djechlin,

2
Il wiki a cui ho collegato in modo molto succinto descrive ciò che è: "Un'espressione di funzione freccia ha una sintassi più breve rispetto alle espressioni di funzione e lega lessicamente questo valore. Le funzioni freccia sono sempre anonime".
Kyle Falconer,

1
Aggiungerlo come preventivo qui aiuterà davvero la tua risposta.
Hanky ​​Panky,

22

Queste sono le funzioni freccia

Conosciuto anche come Fat Arrow Functions . Sono un modo pulito e conciso di scrivere espressioni di funzioni, ad es function() {}.

Freccia Le funzioni possono eliminare la necessità di function, returne {}al momento di definire le funzioni. Sono a linea singola, simili alle espressioni Lambda in Java o Python.

Esempio senza parametri

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

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

Se è necessario fare più istruzioni all'interno della stessa funzione Freccia, è necessario racchiudere, in questo esempio, queue[0]tra parentesi graffe {}. In questo caso la dichiarazione di ritorno non può essere omessa.

Esempio con 1 parametro

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

addCustomer('Toby');

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

Puoi omettere {}da quanto sopra.

Quando è presente un singolo parametro, è ()possibile omettere le parentesi attorno al parametro.

Esempio con più parametri

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

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

Un esempio utile

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

Se volessimo ottenere il prezzo di ogni frutto in un singolo array, in ES5 potremmo fare:

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

In ES6 con le nuove funzioni Arrow, possiamo renderlo più conciso:

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

Ulteriori informazioni sulle funzioni freccia sono disponibili qui .

Compatibilità del browser

  • IE: non ancora supportato
  • Bordo: 12+ (tutte le versioni)
  • Firefox: 22+
  • Chrome: 45+
  • Safari: 10+
  • Safari iOS: 10.2+
  • Browser Android: 56+

Ulteriori informazioni aggiornate sono disponibili sulla compatibilità del browser qui


21

solo per aggiungere un altro esempio di cosa può fare una lambda senza usare 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

13

Come altri hanno già detto, è una nuova sintassi per creare funzioni.

Tuttavia, questo tipo di funzioni differisce da quelle normali:

  • Vincolano il thisvalore. Come spiegato dalle specifiche ,

    Un ArrowFunction non definisce binding locali per arguments, super, this, o new.target. Qualsiasi riferimento a arguments, super, thiso new.targetall'interno di un ArrowFunction deve essere risolto in un legame in un ambiente lessicale racchiude. In genere questo sarà l'ambiente funzionale di una funzione che si chiude immediatamente.

    Anche se una ArrowFunction può contenere riferimenti a super, l'oggetto funzione creato nel passaggio 4 non viene trasformato in un metodo eseguendo MakeMethod . Una ArrowFunction a cui fa riferimento super è sempre contenuta in una non ArrowFunction e lo stato necessario per l'implementazione superè accessibile tramite l' ambito acquisito dall'oggetto funzione di ArrowFunction .

  • Sono non costruttori.

    Ciò significa che non hanno un metodo interno [[Costruisci]] e quindi non possono essere istanziati, ad es

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

8

Ho letto, questo è un simbolo di Arrow FunctionsinES6

Questo

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

l'utilizzo Arrow Functionpuò essere scritto come

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

Documenti MDN


6

Aggiunta di un semplice esempio CRUD con la funzione freccia

 //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)); 

4

Insoddisfatto delle altre risposte. La risposta più votata al 2019/3/13 è di fatto errata.

La versione abbreviata di ciò che =>significa è che è una scorciatoia per scrivere una funzione E per legarla alla correntethis

const foo = a => a * 2;

È effettivamente una scorciatoia per

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

Puoi vedere tutte le cose che sono state accorciate. Non abbiamo avuto bisogno function, return.bind(this)né nemmeno di parentesi graffe o parentesi

Un esempio leggermente più lungo di una funzione freccia potrebbe essere

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

Mostrando che se vogliamo più argomenti per la funzione abbiamo bisogno di parentesi e se vogliamo scrivere più di una singola espressione abbiamo bisogno di parentesi graffe e di un esplicito return .

È importante capire la .bindparte ed è un argomento importante. Ha a che fare con cosathis significa in JavaScript.

TUTTE le funzioni hanno un parametro implicito chiamatothis . Comethis viene impostato quando si chiama una funzione dipende da come viene chiamata quella funzione.

Prendere

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

Se lo chiami normalmente

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

this sarà l'oggetto globale.

Se sei in modalità rigorosa

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

// or

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

Sarà undefined

È possibile impostare thisdirettamente utilizzando calloapply

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}

Puoi anche impostare thisimplicitamente usando l'operatore punto.

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

Un problema si presenta quando si desidera utilizzare una funzione come callback o listener. Si crea classe e si desidera assegnare una funzione come callback che accede a un'istanza della classe.

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

Il codice sopra non funzionerà perché quando l'elemento genera l'evento e chiama la funzione il thisvalore non sarà l'istanza della classe.

Un modo comune per risolvere quel problema è usare .bind

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

Perché la sintassi della freccia fa la stessa cosa che possiamo scrivere

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

bindfa effettivamente una nuova funzione . Se bindnon esistesse, potresti fondamentalmente crearne uno tuo come questo

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

Nel vecchio JavaScript senza l'operatore spread sarebbe

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

Comprendere che il codice richiede una comprensione delle chiusure ma la versione breve è binduna nuova funzione che chiama sempre la funzione originale con il thisvalore che era associato ad essa. la funzione freccia fa la stessa cosa poiché sono una scorciatoia perbind(this)


2

Come hanno già detto tutte le altre risposte, fa parte della sintassi della funzione freccia ES2015. Più specificamente, non è un operatore, è un punctuator token che separa i parametri dal corpo: ArrowFunction : ArrowParameters => ConciseBody. Es (params) => { /* body */ }.


1

ES6 Funzioni freccia:

In javascript =>è il simbolo di un'espressione della funzione freccia. Un'espressione della funzione freccia non ha un proprio thislegame e pertanto non può essere utilizzata come funzione di costruzione. per esempio:

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

Regole di utilizzo delle funzioni freccia:

  • Se esiste esattamente un argomento, puoi omettere le parentesi dell'argomento.
  • Se si restituisce un'espressione e lo si fa sulla stessa riga, è possibile omettere {}l' returnistruzione e

Per esempio:

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));


1

Le funzioni freccia indicate dal simbolo (=>) consentono di creare funzioni e metodi anonimi. Ciò porta a una sintassi più breve. Ad esempio, di seguito è una semplice funzione "Aggiungi" che restituisce l'aggiunta di due numeri.

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

La funzione sopra diventa più corta usando la sintassi "Freccia" come mostrato sotto.

inserisci qui la descrizione dell'immagine

Il codice sopra ha due parti come mostrato nel diagramma sopra: -

Input: - Questa sezione specifica i parametri di input per la funzione anonima.

Logica: - Questa sezione viene dopo il simbolo “=>”. Questa sezione presenta la logica della funzione effettiva.

Molti sviluppatori pensano che la funzione freccia renda la tua sintassi più breve, più semplice e quindi leggibile il tuo codice.

Se credi alla frase sopra, allora lascia che ti assicuri che è un mito. Se pensi per un momento una funzione correttamente scritta con nome è molto leggibile rispetto alle funzioni criptiche create in una riga usando un simbolo freccia.

L'uso principale della funzione freccia è garantire che il codice venga eseguito nel contesto dei chiamanti.

Vedi il codice seguente in cui è definita una variabile globale "contesto", a questa variabile globale si accede all'interno di una funzione "SomeOtherMethod" che viene chiamata dall'altro metodo "SomeMethod".

Questa "SomeMethod" ha una variabile "contesto" locale. Ora, poiché "SomeOtherMethod" viene chiamato da "" SomeMethod ", ci aspettiamo che visualizzi" contesto locale ", ma visualizzi" contesto globale ".

var context = global context”;

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

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

var instance = new SomeMethod();

Ma se sostituisci la chiamata usando la funzione Freccia visualizzerà "contesto locale".

var context = "global context";

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

Ti incoraggio a leggere questo link ( funzione freccia in JavaScript ) che spiega tutti gli scenari del contesto javascript e in quali scenari il contesto dei chiamanti non viene rispettato.

Puoi anche vedere la dimostrazione della funzione Freccia con javascript in questo video di YouTube che dimostra praticamente il termine Contesto.


0

Come altri hanno affermato, le funzioni regolari (tradizionali) utilizzano thisdall'oggetto che ha chiamato la funzione (ad esempio un pulsante su cui è stato fatto clic) . Invece, usano le funzioni frecciathis dall'oggetto che definisce la funzione.

Considera due funzioni quasi identiche:

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


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

Lo snippet seguente mostra la differenza fondamentale tra ciò che thisrappresenta per ciascuna funzione. Le funzioni normali uscite [object HTMLButtonElement]mentre le funzioni freccia uscite [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>

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.