sintaxis - ¿Cuál es el significado de "=>" (una flecha gorda formada por signos de igual y mayor que) en JavaScript?
Sé que el operador >= significa mayor o igual que, pero 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);
Respuesta #1
Qué es
Esta es una función flecha. Las funciones flecha son una sintaxis corta, introducida por ECMAscript 6, que se puede usar de manera similar a la forma en que usarías las expresiones de función. En otras palabras, a menudo puedes usarlas en lugar de expresiones como function (foo) {...}. Pero tienen algunas diferencias importantes. Por ejemplo, no enlazan sus propios valores de this (ver más abajo para una discusión).
Las funciones flecha son parte de la especificación ECMAscript 6. Aún no son compatibles con todos los navegadores, pero son parcialmente o totalmente compatibles con Node v. 4.0+ y con la mayoría de los navegadores modernos en uso a partir de 2018. (He incluido una lista parcial de navegadores compatibles a continuación).
Puedes leer más en la documentación de Mozilla sobre funciones flecha.
De la documentación de Mozilla:
Una expresión de función flecha (también conocida como función de flecha gorda) tiene una sintaxis más corta en comparación con las expresiones de función y enlaza léxicamente el valor de
this(no enlaza su propiothis,arguments,superonew.target). Las funciones flecha siempre son anónimas. Estas expresiones de función son más adecuadas para funciones que no sean métodos y no pueden usarse como constructores.
Una nota sobre cómo this funciona en las funciones flecha
Una de las características más útiles de una función flecha está enterrada en el texto anterior:
Una función flecha... enlaza léxicamente el valor de
this(no enlaza su propiothis...)
Lo que esto significa en términos más simples es que la función flecha retiene el valor de this de su contexto y no tiene su propio this. Una función tradicional puede vincular su propio valor de this, dependiendo de cómo se defina y se llame. Esto puede requerir muchas maniobras como self=this;, etc., para acceder o manipular this de una función dentro de otra función. Para más información sobre este tema, consulta 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
Puedes usar funciones flecha en Node, pero el soporte en los navegadores es irregular.
El soporte del navegador para esta funcionalidad ha mejorado bastante, pero todavía no es lo suficientemente generalizado para la mayoría de los usos basados en navegador. A partir del 12 de diciembre de 2017, está soportado en las versiones actuales de:
- Chrome (v. 45+)
- Firefox (v. 22+)
- Edge (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+)
- iOS Safari (v. 10.2+)
- Samsung Internet (v. 5+)
- Baidu Browser (v. 7.12+)
No compatible con:
- IE (hasta la v. 11)
- Opera Mini (hasta la v. 8.0)
- Navegador Blackberry (hasta la v. 10)
- IE Mobile (hasta la v. 11)
- UC Browser para Android (hasta la v. 11.4)
- QQ (a través de v. 1.2)
Puedes encontrar más información (y más actual) en CanIUse.com (sin afiliación).
Respuesta #2
Eso se conoce como una Función 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,3Sintaxis 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,3DEMO
La otra cosa increíble es léxica this... Usualmente, 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 así:
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
Más sobre Sintaxis
Para más, aquí hay una respuesta bastante buena sobre cuándo usar funciones flecha.
Respuesta #3
Estas son funciones flecha
También conocidas como Funciones Flecha Gorda. Son una forma limpia y concisa de escribir expresiones de función, por ejemplo, function() {}.
Las funciones flecha pueden eliminar la necesidad de function, return y {} al definir 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 se necesitan hacer múltiples declaraciones dentro de la misma función Arrow, necesitas envolver, en este ejemplo, queue[0] entre llaves {}. En este caso, la declaración return no puede omitirse.
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, se pueden omitir los paréntesis () alrededor del parámetro.
Ejemplo con múltiples parámetros
const addNumbers = (x, y) => x + y
console.log(addNumbers(1, 5)); // 6Un 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 un solo arreglo, en ES5 podríamos hacer:
fruits.map(function(fruit) {
return fruit.price;
}); // [2, 3, 1]
En ES6, con las nuevas funciones flecha, podemos hacer esto más conciso:
fruits.map(fruit => fruit.price); // [2, 3, 1]
Se puede encontrar información adicional sobre las funciones flecha aquí.
Respuesta #4
Esta sería la "expresión de función flecha" introducida en ECMAScript 6.
https://developer.mozilla.org/es/docs/Web/JavaScript/Reference/Funciones_flecha
Para fines históricos (si la página del wiki cambia más adelante), es:
Una expresión de función flecha tiene una sintaxis más corta en comparación con las expresiones de función y enlaza léxicamente el valor de this. Las funciones flecha son siempre anónimas.
Respuesta #5
solo para añadir 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
Respuesta #6
Como otros han dicho, es una nueva sintaxis para crear funciones.
Sin embargo, este tipo de funciones difieren de las normales:
Ellos enlazan el valor de
this. Como lo explica la especificación,Una ArrowFunction no define vinculaciones locales para
arguments,super,thisonew.target. Cualquier referencia aarguments,super,thisonew.targetdentro de una ArrowFunction debe resolverse a una vinculación en un entorno léxico que lo encierre. Normalmente, esto será el Entorno de Función de una función que la encierre inmediatamente.Aunque una ArrowFunction pueda 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 ArrowFunction que referencia asupersiempre está contenida dentro de una función no-ArrowFunction y el estado necesario para implementarsuperes accesible a través del scope que es capturado por el objeto de función de la ArrowFunction.Ellos no son constructores.
Eso significa que no tienen un método interno [[Construct]], y por lo tanto no pueden ser instanciados, por ejemplo.
var f = a => a; f(123); // 123 new f(); // TypeError: f is not a constructor
Respuesta #7
Insatisfecho con las otras respuestas. La respuesta con más votos hasta el 13/3/2019 es factualmente incorrecta.
La versión corta y concisa de lo que significa => es que es una forma abreviada de escribir una función Y de vincularla al this actual
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 return, ni .bind(this), ni siquiera llaves o paréntesis
Un ejemplo ligeramente más largo de una función flecha podría ser
const foo = (width, height) => {
const area = width * height;
return area;
};
Mostrando 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 return explícito.
Es importante entender la parte de .bind y es un tema amplio. Tiene que ver con lo que this significa en JavaScript.
TODAS las funciones tienen un parámetro implícito llamado this. Cómo se establece this al llamar a una función depende de cómo se llame 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
Puedes establecer this directamente usando call o apply
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 puedes establecer this implícitamente usando el operador punto .
function foo(msg) { console.log(msg, this); }
const obj = {
abc: 123,
bar: foo,
}
obj.bar('Hola'); // prints Hola {abc:123, bar: f}
Surge un problema cuando quieres usar una función como un callback o un listener. Creas una clase y quieres asignar una función como el callback que acceda 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 dispare el evento y llame a la función, el valor de this 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! ===========
}
}
Porque la sintaxis de flecha hace lo mismo que podemos escribir
class ShowName {
constructor(name, elem) {
this.name = name;
elem.addEventListener('click',() => {
console.log(this.name);
});
}
}
bind efectivamente crea una nueva función. Si bind no existiera, básicamente podrías crear la tuya propia así
function bind(functionToBind, valueToUseForThis) {
return function(...args) {
functionToBind.call(valueToUseForThis, ...args);
};
}
En JavaScript antiguo sin el operador de propagación sería
function bind(functionToBind, valueToUseForThis) {
return function() {
functionToBind.apply(valueToUseForThis, arguments);
};
}
Entender ese código requiere comprender los cierres, pero la versión corta es que bind crea una nueva función que siempre llama a la función original con el valor de this que se le vinculó. Las funciones flecha hacen lo mismo ya que son un atajo para bind(this)
