¿Cuál es el significado de "=>" (una flecha formada a partir de igual y mayor que) en JavaScript?

444

Sé que el >=operador significa más o igual que, pero lo he visto =>en algún código fuente. ¿Cuál es el significado de ese operador?

Aquí está el código:

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

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

    continueSave();
}).then(null, Components.utils.reportError);
rpgs_player
fuente
55
Vea este enlace sobre las funciones de flecha .
Mistalis

Respuestas:

546

Lo que es

Esta es una función de flecha. Las funciones de flecha son una sintaxis corta, introducida por ECMAscript 6, que se puede usar de manera similar a la forma en que usaría expresiones de función. En otras palabras, a menudo puede usarlos en lugar de expresiones como function (foo) {...}. Pero tienen algunas diferencias importantes. Por ejemplo, no vinculan sus propios valores de this(ver más abajo para discusión).

Las funciones de flecha son parte de la especificación ECMAscript 6. Todavía no son compatibles con todos los navegadores, pero son parcial o totalmente compatibles con Node v. 4.0+ y en la mayoría de los navegadores modernos en uso a partir de 2018. (He incluido una lista parcial de navegadores compatibles a continuación).

Puede leer más en la documentación de Mozilla sobre funciones de flecha .

De la documentación de Mozilla:

Una expresión función flecha (también conocida como función de la flecha grasa) tiene una sintaxis más corta en comparación con las expresiones de función y léxico se une el thisvalor (no se une a su propio this, arguments, super, o new.target). Las funciones de flecha son siempre anónimas. Estas expresiones de función son más adecuadas para funciones que no son de método y no pueden usarse como constructores.

Una nota sobre cómo thisfunciona en las funciones de flecha

Una de las características más útiles de una función de flecha está enterrada en el texto anterior:

Una función de flecha ... vincula léxicamente el thisvalor (no vincula su propio this...)

Lo que esto significa en términos más simples es que la función de flecha retiene el thisvalor de su contexto y no tiene el suyo this. Una función tradicional puede unir su propio thisvalor, dependiendo de cómo se define y se llama. Esto puede requerir mucha gimnasia como self = this;, etc., para acceder o manipular thisdesde una función dentro de otra función. Para obtener más información sobre este tema, consulte la explicación y los ejemplos en la documentación de Mozilla .

Código de ejemplo

Ejemplo (también de los documentos):

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]

Notas sobre compatibilidad

Puede usar las funciones de flecha en Node, pero el soporte del navegador es irregular.

El soporte del navegador para esta funcionalidad ha mejorado bastante, pero aún no está lo suficientemente extendido para la mayoría de los usos basados ​​en el navegador. A partir del 12 de diciembre de 2017, es compatible con las versiones actuales de:

  • Chrome (v. 45+)
  • Firefox (v. 22+)
  • Borde (v. 12+)
  • Opera (v. 32+)
  • Navegador de Android (v. 47+)
  • Opera Mobile (v. 33+)
  • Chrome para Android (v. 47+)
  • Firefox para Android (v. 44+)
  • Safari (v. 10+)
  • Safari de iOS (v. 10.2+)
  • Internet de Samsung (v. 5+)
  • Navegador Baidu (v. 7.12+)

No soportado en:

  • IE (hasta el v. 11)
  • Opera Mini (hasta la versión 8.0)
  • Navegador Blackberry (hasta el v. 10)
  • IE Mobile (a través de v. 11)
  • UC Browser para Android (hasta la v. 11.4)
  • QQ (hasta v. 1.2)

Puede encontrar más información (y más actual) en CanIUse.com (sin afiliación).

elixenida
fuente
3
TypeScript también parece admitirlo.
mtyson
1
Parece que esta es una expresión lambda, ¿sí?
Admitir el
1
Quería mencionar en términos de compatibilidad del navegador que uso las funciones de flecha ES6 / ES7 y otras características que no son compatibles con IE11 de forma nativa, pero uso Gulp o Webpack junto con Babel para transpilar ES6 a ES5 para que funcione en IE11. Entonces, si necesita soporte para IE11 y no le importa configurar Babel, hágalo.
mbokil
76

Eso se conoce como una función de flecha, parte de la especificación ECMAScript 2015 ...

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

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

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

Sintaxis más corta que la anterior:

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

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

MANIFESTACIÓN

La otra cosa increíble es léxica this ... Por lo general, harías algo como:

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

Pero eso podría reescribirse con la flecha como esta:

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

MANIFESTACIÓN

MDN
Más sobre sintaxis

Para más información, aquí hay una respuesta bastante buena sobre cuándo usar las funciones de flecha.

Brbcoding
fuente
Sería bueno actualizar las demos para usar esfiddle.net ya que es6fiddle.net ya no está operativo
Wavesailor
25

Esta sería la "expresión de función de flecha" introducida en ECMAScript 6.

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

Para fines históricos (si la página wiki cambia más adelante), es:

Una expresión de función de flecha tiene una sintaxis más corta en comparación con las expresiones de función y enlaza léxicamente este valor. Las funciones de flecha son siempre anónimas.

Kyle Falconer
fuente
1
¿Le importaría incluir suficiente información para que la mayoría de los lectores no tengan que profundizar?
djechlin
2
La wiki a la que enlacé describe muy sucintamente lo que es: "Una expresión de función de flecha tiene una sintaxis más corta en comparación con las expresiones de función y enlaza léxicamente este valor. Las funciones de flecha son siempre anónimas".
Kyle Falconer
1
Agregar eso como una cita aquí realmente ayudará a su respuesta.
Hanky ​​Panky
22

Estas son funciones de flecha

También conocido como Fat Arrow Functions . Son una forma limpia y concisa de escribir expresiones de funciones, por ej.function() {} .

Funciones flecha puede eliminar la necesidad de function, returny{} en la definición de funciones. Son de una sola línea, similares a las expresiones Lambda en Java o Python.

Ejemplo sin parámetros

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

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

Si es necesario realizar varias declaraciones dentro de la misma función de flecha, debe ajustar, en este ejemplo, queue[0]entre paréntesis{} . En este caso, la declaración de devolución no se puede omitir.

Ejemplo con 1 parámetro

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

addCustomer('Toby');

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

Puedes omitir {} de lo anterior.

Cuando hay un solo parámetro, los corchetes () se pueden omitir alrededor del parámetro.

Ejemplo con múltiples parámetros

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

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

Un ejemplo útil

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

Si quisiéramos obtener el precio de cada fruta en una sola matriz, en ES5 podríamos hacer:

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

En ES6 con las nuevas funciones de flecha, podemos hacer esto más conciso:

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

Puede encontrar información adicional sobre las funciones de flecha aquí .

Compatibilidad del navegador

  • IE: no admitido todavía
  • Edge: 12+ (todas las versiones)
  • Firefox: 22+
  • Chrome: 45+
  • Safari: 10+
  • Safari de iOS: 10.2+
  • Navegador de Android: 56+

Puede encontrar información actualizada adicional sobre la compatibilidad del navegador aquí

Toby Mellor
fuente
21

solo para agregar otro ejemplo de lo que una lambda puede hacer sin usar 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
fuente
13

Como otros han dicho, es una nueva sintaxis para crear funciones.

Sin embargo, este tipo de funciones difieren de las normales:

  • Atan el thisvalor. Como se explica en la especificación ,

    Un ArrowFunction no define fijaciones locales para arguments, super, this, o new.target. Cualquier referencia a arguments, super, this, o new.targetdentro de un ArrowFunction debe resolver a una consolidación en un entorno léxico que encierra. Normalmente, este será el entorno de función de una función de cierre inmediato.

    Aunque una función de flecha puede contener referencias a super, el objeto de función creado en el paso 4 no se convierte en un método al realizar MakeMethod . Una función de flecha que hace referencia super siempre está contenida dentro de una función que no es de flecha y superse puede acceder al estado necesario para implementar a través del alcance capturado por el objeto de función de la función de flecha .

  • Son no constructores.

    Eso significa que no tienen un método interno [[Construir]] y, por lo tanto, no se pueden crear instancias, por ejemplo

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

He leído, este es un símbolo de Arrow Functions enES6

esta

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

utilizando Arrow Functionse puede escribir como

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

MDN Docs

Mritunjay
fuente
6

Agregar un ejemplo CRUD simple con 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
fuente
4

Insatisfecho con las otras respuestas. La respuesta más votada a partir del 3/3/13 es objetivamente errónea.

La versión abreviada de lo que =>significa es que es un acceso directo que escribe una función Y para vincularla a la actualthis

const foo = a => a * 2;

Es efectivamente un atajo para

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

Puedes ver todas las cosas que se acortaron. No necesitábamos function, ni returntampoco .bind(this)ni siquiera llaves o paréntesis

Un ejemplo un poco más largo de una función de flecha podría ser

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

Demostrando que si queremos múltiples argumentos para la función necesitamos paréntesis y si queremos escribir más de una sola expresión, necesitamos llaves y un código explícito return .

Es importante entender la .bindparte y es un gran tema. Tiene que ver con lo quethis significa en JavaScript.

TODAS las funciones tienen un parámetro implícito llamado this. Cómothis se establece cuando se llama a una función depende de cómo se llama esa función.

Tomar

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

Si lo llamas normalmente

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

this Será el objeto global.

Si estás en modo estricto

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

// or

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

Será undefined

Puede configurar thisdirectamente usando 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}

También puede establecer thisimplícitamente utilizando el operador de 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 surge cuando desea utilizar una función como una devolución de llamada o un oyente. Hace la clase y desea asignar una función como la devolución de llamada que accede a una instancia de la clase.

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

El código anterior no funcionará porque cuando el elemento activa el evento y llama a la función, el thisvalor no será la instancia de la clase.

Una forma común de resolver ese problema es usar .bind

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

Debido a que la sintaxis de la flecha hace lo mismo que podemos escribir

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

bindEfectivamente hace una nueva función . Si bindno existiera, básicamente podría hacer el suyo así

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

En JavaScript anterior sin el operador de propagación sería

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

Comprender que el código requiere una comprensión de los cierres, pero la versión corta es binduna nueva función que siempre llama a la función original con el thisvalor que estaba vinculado a ella. la función de flecha hace lo mismo ya que son un atajo parabind(this)

gman
fuente
2

Como todas las otras respuestas ya han dicho, es parte de la sintaxis de la función de flecha ES2015. Más específicamente, no es un operador, que es una Punctuator token que separa los parámetros desde el cuerpo: ArrowFunction : ArrowParameters => ConciseBody. Por ej (params) => { /* body */ }.

JMM
fuente
1

ES6 Funciones de flecha:

En javascript, =>es el símbolo de una expresión de función de flecha. Una expresión de función de flecha no tiene su propio thisenlace y, por lo tanto, no se puede usar como una función constructora. por ejemplo:

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

Reglas de uso de funciones de flecha:

  • Si hay exactamente un argumento, puede omitir los paréntesis del argumento.
  • Si devuelve una expresión y hace esto en la misma línea, puede omitir el {}y la returndeclaración

Por ejemplo:

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

Las funciones de flecha que se denotan con el símbolo (=>) lo ayudan a crear funciones y métodos anónimos. Eso lleva a una sintaxis más corta. Por ejemplo, a continuación hay una función simple "Agregar" que devuelve la suma de dos números.

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

La función anterior se acorta utilizando la sintaxis de "Flecha" como se muestra a continuación.

ingrese la descripción de la imagen aquí

El código anterior tiene dos partes como se muestra en el diagrama anterior: -

Entrada: esta sección especifica los parámetros de entrada para la función anónima.

Lógica: esta sección viene después del símbolo "=>". Esta sección tiene la lógica de la función real.

Muchos desarrolladores piensan que la función de flecha hace que su sintaxis sea más corta, simple y, por lo tanto, hace que su código sea legible.

Si crees en la oración anterior, déjame asegurarte que es un mito. Si piensa por un momento, una función escrita correctamente con nombre es mucho más legible que las funciones crípticas creadas en una línea usando un símbolo de flecha.

El uso principal de la función de flecha es garantizar que el código se ejecute en el contexto de las personas que llaman.

Consulte el siguiente código en el que se define una variable global "contexto", se accede a esta variable global dentro de una función "SomeOtherMethod" que se llama desde otro método "SomeMethod".

Este "SomeMethod" tiene una variable de "contexto" local. Ahora porque "SomeOtherMethod" se llama desde "" SomeMethod "esperamos que muestre" contexto local ", pero muestra" contexto global ".

var context = global context”;

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

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

var instance = new SomeMethod();

Pero si reemplaza la llamada con la función de flecha, mostrará "contexto local".

var context = "global context";

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

Te animo a leer este enlace ( función de flecha en JavaScript ) que explica todos los escenarios del contexto de JavaScript y en qué escenarios no se respeta el contexto de las personas que llaman.

También puede ver la demostración de la función de flecha con javascript en este video de youtube que muestra prácticamente el término Contexto.

Shivprasad Koirala
fuente
0

Como han dicho otros, las funciones regulares (tradicionales) se utilizan thisdesde el objeto que llamó a la función (por ejemplo, un botón en el que se hizo clic) . En cambio, las funciones de flecha se usan thisdesde el objeto que define la función.

Considere dos funciones casi idénticas:

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


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

El fragmento a continuación muestra la diferencia fundamental entre lo que thisrepresenta para cada función. La función regular sale [object HTMLButtonElement]mientras que la función de flecha sale [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>

Aprendiz lento
fuente