tl; dr: ¡No! Las funciones de flecha y las declaraciones / expresiones de función no son equivalentes y no se pueden reemplazar a ciegas.
Si la función que desea reemplazar no no usar this
, arguments
y no se llama con new
, entonces sí.
Como tan a menudo: depende . Las funciones de flecha tienen un comportamiento diferente que las declaraciones / expresiones de función, así que echemos un vistazo a las diferencias primero:
1. Lexical this
yarguments
Las funciones de flecha no tienen sus propias this
o arguments
vinculantes. En cambio, esos identificadores se resuelven en el ámbito léxico como cualquier otra variable. Eso significa que dentro de una función de flecha, this
y se arguments
refieren a los valores de this
y arguments
en el entorno, la función de flecha se define en (es decir, "fuera" de la función de flecha):
// Example using a function expression
function createObject() {
console.log('Inside `createObject`:', this.foo);
return {
foo: 42,
bar: function() {
console.log('Inside `bar`:', this.foo);
},
};
}
createObject.call({foo: 21}).bar(); // override `this` inside createObject
// Example using a arrow function
function createObject() {
console.log('Inside `createObject`:', this.foo);
return {
foo: 42,
bar: () => console.log('Inside `bar`:', this.foo),
};
}
createObject.call({foo: 21}).bar(); // override `this` inside createObject
En el caso de expresión de función, se this
refiere al objeto que se creó dentro de createObject
. En el caso la función de flecha, this
se refiere a this
de createObject
sí mismo.
Esto hace que las funciones de flecha sean útiles si necesita acceder al this
entorno actual:
// currently common pattern
var that = this;
getData(function(data) {
that.data = data;
});
// better alternative with arrow functions
getData(data => {
this.data = data;
});
Tenga en cuenta que esto también significa que no es posible establecer una función de flecha this
con .bind
o .call
.
Si no está muy familiarizado this
, considere leer
2. Las funciones de flecha no se pueden invocar con new
ES2015 distingue entre funciones que se pueden llamar y funciones que se pueden construir . Si una función es construible, se puede llamar con new
, es decir new User()
. Si una función es invocable, se puede new
invocar sin ella (es decir, llamada a función normal).
Las funciones creadas a través de declaraciones / expresiones de funciones son tanto construibles como invocables.
Las funciones de flecha (y métodos) solo son invocables.
class
Los constructores son solo construibles.
Si está intentando llamar a una función no invocable o construir una función no construible, obtendrá un error de tiempo de ejecución.
Sabiendo esto, podemos decir lo siguiente.
Reemplazable:
- Funciones que no usan
this
o arguments
.
- Funciones que se usan con
.bind(this)
No reemplazable:
- Funciones de constructor
- Función / métodos agregados a un prototipo (porque generalmente se usan
this
)
- Funciones variables (si usan
arguments
(ver más abajo))
Echemos un vistazo más de cerca a esto usando sus ejemplos:
Función constructora
Esto no funcionará porque las funciones de flecha no se pueden invocar con new
. Siga usando una declaración / expresión de función o uso class
.
Métodos prototipo
Lo más probable es que no, porque los métodos prototipo generalmente se usan this
para acceder a la instancia. Si no lo usan this
, puede reemplazarlo. Sin embargo, si le interesa principalmente la sintaxis concisa, use class
con su sintaxis de método conciso:
class User {
constructor(name) {
this.name = name;
}
getName() {
return this.name;
}
}
Métodos de objeto
Del mismo modo para los métodos en un objeto literal. Si el método quiere hacer referencia al objeto en sí mismo this
, siga usando expresiones de función o use la nueva sintaxis del método:
const obj = {
getName() {
// ...
},
};
Devoluciones de llamada
Depende. Definitivamente deberías reemplazarlo si estás aliasando el exterior this
o estás usando .bind(this)
:
// old
setTimeout(function() {
// ...
}.bind(this), 500);
// new
setTimeout(() => {
// ...
}, 500);
Pero: si el código que llama a la devolución de llamada se establece explícitamente this
en un valor específico, como suele ser el caso con los controladores de eventos, especialmente con jQuery, y la devolución de llamada usa this
(o arguments
), ¡ no puede usar una función de flecha!
Funciones variadas
Dado que las funciones de flecha no tienen las suyas propias arguments
, no puede simplemente reemplazarlas con una función de flecha. Sin embargo, ES2015 presenta una alternativa al uso arguments
: el parámetro rest .
// old
function sum() {
let args = [].slice.call(arguments);
// ...
}
// new
const sum = (...args) => {
// ...
};
Pregunta relacionada:
Recursos adicionales: