Pasar al contenido principal

JavaScript: Arrays que no son arrays

JavaScript: Arrays que no son arrays

JavaScript: Arrays que no son arrays - Escuela Digital

En JavaScript existe un tipo especial de objeto llamado comunmente array-like (parecido a un array) y es que a la vista parece ser un array, valores separados por comas, encerrados en corchetes, se puede accedr a sus elementos con [i]. Sin embargo, cuando intentamos usar métodos como .map() .reduce() .slice(), etc el intérprete nos arroja un error, demostrandonos que no estamos realmente frente a un array. Y cuando comenzamos con JavaScript no conocer este detalle puede ser realmente frustrante.

El caso más conocido es el objeto arguments que lista los argumentos pasados al ejecutar una función. Supongamos que queremos obtener la suma de todos los argumentos pasados a una función. Sin importar cuántos son:

let sum = function(){
  arguments.reduce((a,b) => a + b);
}

console.log(sum(1,2,3)); // TypeError: arguments.reduce is not a function

Puesto que no es una array y no podemos usar .reduce() no nos queda más que iterar:

let sum = function(){
  let total = 0;
  for(let i = 0; i < arguments.length; i++) {
    total += arguments[i];
  }
  return total;
}

console.log(sum(1,2,3)) // 6

¿Y los parámetros rest en ES6?

Los parámetros rest en ES6 indican que una función puede recibir un número indefinido de argumentos. Y la ventaja frente a arguments es que este es un array, no un array-like. Veamos el ejemplo nuevamente:

let sum = function(...args){
  return args.reduce((a,b) => a + b);
}

console.log(sum(1,2,3)); // 6

Objetos array-like y el DOM

Cuando interactuamos con el DOM por ejemplo con document.querySelectorAll(), element.classList, element.children, etc. recibimos nuevamente un array-like, no un array, aunque lo parezca. Técnicamente recibimos un NodeList o un DOMTokenList.

Convertir un array-like a un array

Para el caso anterior (manipular el DOM) se hace necesario convertir los objetos array-like a arrays para poder operar sobre ellos. De hecho, jQuery nos facilita ese trabajo:

$('a').css('color', 'green');

Pero lo siguiente no funcionará en Vanilla JS:

let links = document.querySelectorAll('a');
links.map(link => link.style.color = 'red')

Para convertirlo en un array real usaremos el método .slice de Array.prototipe Este método crea una copia comor array y el método .apply nos permite pasar el objeto original al que se aplicará .slice().

let linksArr = Array.prototype.slice.apply(links)

Por tanto, con Vanilla JS, el ejemplo anterior que usaba jQuery quedaría así:

let links = document.querySelectorAll('a');
let linksArr = Array.prototype.slice.apply(links);
linksArr.map(link => link.style.color = 'red');

¿Quieres saber más? Inscríbete a nuestro curso JavaScript Desde Cero. 25 horas de clase con proyecto de fin de curso, contenidos bonus y respuestas a tus consultas:
http://escuela.digital/js