¿alguna vez has experimentado detalles curiosos de javascript durante del desarrollo o investigacion? cosas que normalmente no se habla o detallan en las documentaciones, manuales o tutoriales. pues de eso se trata este tema.
hoy estaba experimentando y analizando con el metodo forEach de los arrays el cual se estandarizo en la quinta edicion de ECMAScript. un metodo de gran utilidad que servira como sustituto de los bucles para recorrer arrays. sin embargo, me preguntaba por que no habia algo similar para los objetos. la respuesta mas obvia podria ser porque tenemos el bucle for/in. a pesar de ello, es posible tomar prestado las funciones de un constructor y aplicarlo a un tipo de objeto que no pertenece al mismo constructor. especificamente me refiero a emplear los metodos apply o call sobre un objeto con funciones ajenas. entonces, ¿que pasaria si aplicamos forEach sobre un objeto? en teoria, nada. el siguiente ejemplo asi parece demostrarlo al no producirse un resultado en la consola de javascript. el mismo ejemplo en un array deberia imprimir todos los argumentos de la funcion en cada ciclo.
Código:
sin embargo, lo realmente curioso es qué sucederia si definimos el objeto como un array, es decir con indices y propiedad length. curiosamente la funcion opera sobre el objeto.// forEach sobre un objeto, no produce resultado ; [].forEach.call({s:"string", n:0, b:true}, function(v,k,o){console.log(arguments);}); // forEach sobre array, muestra los argumentos por ciclo ; // en este caso no tiene sentido utilizar call o apply puesto ; // que se aplicara sobre el mismo array ; ["string", 0, true].forEach(function(v,k,a){console.log(arguments);});
Código:
segun las pruebas que hice, para que algunos de los metodos de array puedan funcionar es necesario la existencia de la propiedad length con un valor que al menos pueda cubrir el indice mas alto del objeto. es decir...[].forEach.call({"0":"string", "1":0, "2":true, "length":3}, function(v,k,o){console.log(arguments);});
Código:
en el caso de otros funciones, el resultado dependera de la existencia de la propiedad length. por ejemplo, push no toma en consideracion si existe un indice ya definido ya que este se deja llevar por el valor de length. lo que significa que puede sobreescribir un indice ya definido.// notese la peculiaridad, la longitud es 8 y el indice 2 no esta definido ; {"0":"string", "1":0, "3":true, "length":8};
Código:
como cierre, personalmente no le encuentro utilidad definir un objeto como array porque para eso estan los arrays. al mismo tiempo, quizas el observar este comportamiento ayude a responder o replantear algunas incognitas. por ejemplo, eso explicaria por que al asignar como valor cero a length de un array vacia el mismo. o por que typeof devuelve como string "object" en un array y no un string "array". se pudiera debatir si los indices de un array en realidad son propiedades. que por cierto, por alguna razon estas son devueltas en un bucle for/in.// length no existe por tanto lo crea y parte desde 0 sobreescribiendo asi el indice ; var obj = {"0":null}; [].push.call(obj, "value"); console.log(obj); // en este caso el proximo valor agregado sera el indice 3 ; var obj = {"0":null, length: 3}; [].push.call(obj, "value"); console.log(obj);
buscando en la web encontre un tema en stackoverflow donde enumeran caracteristicas ocultas -o curiosidades, si se le puede llamar asi- de javascript. hasta donde llegue, algunas son triviales. otras son poco conocidas porque no se detallan en muchos de los manuales de javascript. en fin, ¿has experimentado alguna curiosidad? ¡animate y compartela!