This is a new technology, part of the ECMAScript 2015 (ES6) standard.
This technology's specification has been finalized, but check the compatibility table for usage and implementation status in various browsers.
La expresión de función flecha (también conocida como función flecha gruesa) dispone de una sintaxis más corta comparada con la expresión de función convencional y vincula contextualmente el valor de this. Las Funciones Flecha siempre son anónimas.
Sintaxis
// Sintaxis básica: (param1, param2, paramN) => { statements } (param1, param2, paramN) => expression // equivalente a: => { return expression; } // Los paréntesis son opcionales cuando solo dispone de un argumento: singleParam => { statements } singleParam => expression // Una función sin argumentos requiere paréntesis: () => { statements } // Avanzado: // Incluir entre paréntesis el cuerpo para retornar un objeto literal: params => ({foo: bar}) // Soporta Parámetros rest (param1, param2, ...rest) => { statements }
Consulta ejemplos de sintaxis más detallados aquí.
Descripción
Consulta también "ES6 In Depth: Arrow functions" on hacks.mozilla.org.
La inclusión de las Funciones Flecha se vieron influenciadas por dos factores: Sintaxis reducida y
this
contextual.
Funciones reducidas
En algunos patrones funcionales, se agradece disponer de funciones reducidas. Compara:
var a = [ "Hydrogen", "Helium", "Lithium", "Beryllium" ]; var a2 = a.map(function(s){ return s.length }); var a3 = a.map( s => s.length );
this
Contextual
Anterior a las funciones flecha, cada nueva función definía su propio valor de this
(un nuevo objeto en el caso de un constructor, undefined en llamadas a funciones en modo estricto, el objeto contextual si la función se llama como un "método de un objeto", etc.). Lo cual resultaba molesto cuando se intentaba aplicar programación orientada a objetos.
function Person() {
// El constructor Person() define `this`
como una instancia de sí mismo.
this.age = 0;
setInterval(function growUp() {
// En modo no estricto, la función growUp() define `this`
// como el objeto global, el cual es diferente al objeto `this`
// definido por el constructor Person().
this.age++;
}, 1000);
}
var p = new Person();
En ECMAScript 3/5, este problema fué corregido asignándosele el valor de this
a una variable por fuera de la función interna.
function Person() { var self = this; // Algunas personas prefieren `that` en lugar de `self`. // Escoja cualquiera pero sea consistente. self.age = 0; setInterval(function growUp() { // La función tipo callback apunta a la variable `self` la cual // contiene el objeto esperado. self.age++; }, 1000); }
Alternativamente, el método bind puede ser utilizado para crear una functión donde podremos asignar this
al valor deseado, de está forma podemos pasar this
a la función growUp()
.
Las funciones de flecha capturan el valor de this
del contexto actual, por lo tanto el código funciona como se espera.
function Person(){ this.age = 0; setInterval(() => { this.age++; // |this| apunta al objeto person }, 1000); } var p = new Person();
Relación con modo estricto (sctrict mode)
Debido a que this
es contextual, las reglas de modo estricto asociadas a este
son simplemente ignoradas.
var f = () => {'use strict'; return this}; f() === window; // or the global object
El resto de reglas asociadas a modo estricto aplican de forma normal.
Función de flecha invocada a través de los métodos call y apply
Debido a que en las funciones de flecha el valor de this
es asignado de forma predefinida, aunque invocar una función de flecha a través de los métodos call()
o apply()
es posible, su ejecución no tendrá en cuenta la asignación arbitraria de this
:
var adder = { base : 1, add : function(a) { var f = v => v + this.base; return f(a); }, addThruCall: function(a) { var f = v => v + this.base; var b = { base : 2 }; return f.call(b, a); } }; console.log(adder.add(1)); // Imprime 2 como es esperado console.log(adder.addThruCall(1)); // También imprime 2 aunque se esperaba 3
Argumentos contextuales
Las funciones de flecha no exponen un objeto arguments
por lo que referenciar arguments.length
, arguments[0]
, arguments[1]
, etc . resultan en errores de referencia no existente. En este caso, arguments
puede hacer referencia a una variable arbitraria:
var arguments = 42;
var arr = () => arguments;
arr(); // 42
function foo() {
var f = () => arguments[0]; // Referencia al objeto arguments
return f(2);
}
foo(1); // 1
Las funciones de flecha no tienen su propio objeto arguments
, por lo que el parámetro rest es la alternativa en este caso:
function foo() { var f = (...args) => args[0]; return f(2); } foo(1); // 2
Uso de la expresión yield
La expresión yield
no puede ser usada dentro de una función de flecha (excepto dentro de funciones tradicionales anidadas). Como consecuencia, las funciones de flecha no pueden ser usadas como funciones generadoras.
Retorno de objetos literales
Tenga en cuenta que retornar objetos literales usando la sintáxis simplificada => {propiedad:valor}
no funciona como se esperaría:
var func = () => { foo: 1 }; // Al llamar func() retorna undefined! var func = () => { foo: function() {} }; // Error de sintaxis: SyntaxError: function statement requires a name
Eso es debido a que el código dentro de las llaves ({}) es leído como una secuencia de sentencias (p.ej foo
es tratado como una etiqueta o label y no como una propiedad del objeto literal).
En este caso, recuerde encerrar el objeto literal entre paréntesis:
var func = () => ({ foo: 1 });
Ejemplos
// Una función de flecha vacía retorna undefined let empty = () => {}; (() => "foobar")() // retorna "foobar" var simple = a => a > 15 ? 15 : a; simple(16); // 15 simple(10); // 10 let max = (a, b) => a > b ? a : b; // Métodos de arreglos como filtering, mapping mas sencillos... var arr = [5, 6, 13, 0, 1, 18, 23]; var sum = arr.reduce((a, b) => a + b); // 66 var even = arr.filter(v => v % 2 == 0); // [6, 0, 18] var double = arr.map(v => v * 2); // [10, 12, 26, 0, 2, 36, 46] //Encadenamiento de promesas de manera sencilla promise.then(a => { // ... }).then(b => { // ... });
Especificaciones
Especificación | Estado | Comentario |
---|---|---|
ECMAScript 2015 (6th Edition, ECMA-262) The definition of 'Arrow Function Definitions' in that specification. |
Standard | Definición inicial. |
Compatibilidad en navegadores
Característica | Chrome | Firefox (Gecko) | IE/Edge | Opera | Safari |
---|---|---|---|---|---|
Soporte básico | 45.0 | 22.0 (22.0) |
Edge 12 |
32 | No support |
Característica | Android | Android Webview | Firefox Mobile (Gecko) | IE Mobile | Opera Mobile | Safari Mobile | Chrome for Android |
---|---|---|---|---|---|---|---|
Basic support | No support | 45.0 | 22.0 (22.0) | No support | No support | No support | 45.0 |
Notas específicas para Firefox
- Implementaciones iniciales de función flecha activaban automáticamente modo estricto. Esto ha cambiado a partir de Firefox 24 donde el uso de
"use strict"
es requerido. - La función de flecha es semánticamente diferente a la implementada en versiones anteriores de Firefox, la cual no eran estándar Expression Closures estas fueron añadidas en Firefox 3 (detalles: Javascript 1.8), para Expression Closures no asigna
this
al contextothis
actual. - Antes de Firefox 39, un salto de línea (
\n
) era incorrectamente permitido despues de los argumentos de la función de flecha. Esto ha sido corregido para alinearse con la especificación de ES2015, por lo tanto código como() \n => {}
arrojaráSyntaxError
a partir de la versión 39.