Qué es una función de primera clase en JavaScript

Resumen: en este tutorial, aprenderás que las funciones de JavaScript son muy importantes al momento de desarrollar una aplicación. Puedes almacenar funciones en variables, pasarlas a otras funciones como argumentos y devolverlas desde otras funciones como valores.
Almacenamiento de funciones en variables
Las funciones son ciudadanos de primera clase en JavaScript. En otras palabras, puedes tratar funciones como valores de otros tipos.
Cuando un lenguaje de programación tiene la capacidad de tratar funciones como valores, pasarlas como argumentos y devolver una función a otra función, entonces se dice que el lenguaje de programación tiene funciones de primera clase y las funciones se llaman ciudadanos de primera clase en ese lenguaje de programación, como es el caso de JavaScript.
Lo siguiente define la función add()
y asigna el nombre de la función a la variable sum
:
function add(a, b) {
return a + b;
}
let sum = add;
En la instrucción de asignación, no incluimos los paréntesis de apertura y cierre al final del identificador de adición. Tampoco ejecutamos la función, sino que hacemos referencia a la función.
Al hacer esto, puedes tener dos formas de ejecutar la misma función. Por ejemplo, llamarla normalmente de la siguiente manera:
let result = add(10, 20);
Alternativamente, puedes usar la función add()
a través de la variable sum de esta manera:
let result = sum(10,20);
Pasar una función a otra función
Como las funciones son valores, puedes pasar una función como argumento a otra función.
Lo siguiente declara la función average()
que toma tres argumentos. El tercer argumento es una función:
function average(a, b, fn) {
return fn(a, b) / 2;
}
Ahora, puede pasar la función sum
a la función average()
de la siguiente manera:
let result = average(10, 20, sum);
Aquí esta todo el código junto:
function add(a, b) {
return a + b;
}
let sum = add;
function average(a, b, fn) {
return fn(a, b) / 2;
}
let result = average(10, 20, sum);
console.log(result);
Te imaginas cual es el resultado que imprime en la consola, es correcto, este es el resultado:
'15'
Devolver funciones desde funciones
Dado que las funciones son valores, puedes devolver una función desde otra función.
La siguiente función compareBy()
devuelve una función que compara dos objetos por una propiedad:
function compareBy(propertyName) {
return function (a, b) {
let x = a[propertyName],
y = b[propertyName];
if (x > y) {
return 1;
} else if (x < y) {
return -1;
} else {
return 0;
}
};
}
Ten en cuenta que a[propertyName]
devuelve el valor de propertyName
de un objeto. Es equivalente a a.propertyName
. Sin embargo, si propertyName
contiene un espacio como 'Precio de descuento', debes usar la notación de corchetes para acceder a él.
Supongamos que tienes una matriz de objetos de producto donde cada objeto de producto tiene dos propiedades: nombre y precio.
let products = [
{name: 'iPhone', price: 900},
{name: 'Samsung Galaxy', price: 850},
{name: 'Sony Xperia', price: 700}
];
Puedes ordenar una matriz llamando al método sort() . El método sort()
acepta una función que compara dos elementos de la matriz como argumento.
Por ejemplo, puedes ordenar los objetos del producto según el nombre pasando una función devuelta por la función compareBy() de la siguiente manera:
console.log('Products sorted by name:');
products.sort(compareBy('name'));
console.table(products);
El resultado es el siguiente:
Products sorted by name:
+------------------------------------+
¦ (index) ¦ name ¦ price ¦
+---------+------------------+-------¦
¦ 0 ¦ 'Samsung Galaxy' ¦ 850 ¦
¦ 1 ¦ 'Sony Xperia' ¦ 700 ¦
¦ 2 ¦ 'iPhone' ¦ 900 ¦
+------------------------------------+
Del mismo modo, puedes ordenar los objetos de productos por el precio
// sort products by prices
console.log('Products sorted by price:');
products.sort(compareBy('price'));
console.table(products);
El resultado es el siguiente:
Products sorted by price:
+------------------------------------+
¦ (index) ¦ name ¦ price ¦
+---------+------------------+-------¦
¦ 0 ¦ 'Sony Xperia' ¦ 700 ¦
¦ 1 ¦ 'Samsung Galaxy' ¦ 850 ¦
¦ 2 ¦ 'iPhone' ¦ 900 ¦
+------------------------------------+
Aquí esta todo el código junto:
function compareBy(propertyName) {
return function (a, b) {
let x = a[propertyName],
y = b[propertyName];
if (x > y) {
return 1;
} else if (x < y) {
return -1;
} else {
return 0;
}
};
}
let products = [
{ name: 'iPhone', price: 900 },
{ name: 'Samsung Galaxy', price: 850 },
{ name: 'Sony Xperia', price: 700 },
];
// sort products by name
console.log('Products sorted by name:');
products.sort(compareBy('name'));
console.table(products);
// sort products by price
console.log('Products sorted by price:');
products.sort(compareBy('price'));
console.table(products);
Más ejemplos de funciones de ciudadanos de primera clase con JavaScript
El siguiente ejemplo define dos funciones que convierten una longitud en centímetros a pulgadas y viceversa:
function cmToIn(length) {
return length / 2.54;
}
function inToCm(length) {
return length * 2.54;
}
La siguiente función convert()
tiene dos parámetros. El primer parámetro es una función y el segundo es la longitud que se convertirá en función del primer argumento:
function convert(fn, length) {
return fn(length);
}
Para convertir cm a in, puede llamar a la función convert()
y pasar la función cmToIn a la función convert()
como primer argumento:
let inches = convert(cmToIn, 10);
console.log(inches);
Resultado:
3.937007874015748
De manera similar, para convertir una longitud de pulgadas a centímetros, puede spasar la función inToCm
a la función convert()
, así:
let cm = convert(inToCm, 10);
console.log(cm);
Resultado:
25.4
Aquí esta todo el código completo:
function cmToIn(length) {
return length / 2.54;
}
function inToCm(length) {
return length * 2.54;
}
function convert(fn, length) {
return fn(length);
}
let inches = convert(cmToIn, 10);
console.log(inches);
let cm = convert(inToCm, 10);
console.log(cm);
Resultado:
3.937007874015748
25.4
Resumen
- Las funciones son ciudadanos de primera clase en JavaScript.
- Puedes pasar funciones a otras funciones como argumentos, devolverlas desde otras funciones como valores y almacenarlas en variables.