Foros del Web » Programando para Internet » Javascript »

curiosidades de javascript

Estas en el tema de curiosidades de javascript en el foro de Javascript en Foros del Web. que tal comunidad! ¿alguna vez has experimentado detalles curiosos de javascript durante del desarrollo o investigacion? cosas que normalmente no se habla o detallan en ...
  #1 (permalink)  
Antiguo 03/04/2011, 22:08
Avatar de zerokilled
Javascripter
 
Fecha de Ingreso: abril-2009
Ubicación: Isla del Encanto, La Borinqueña [+>==]
Mensajes: 8.050
Antigüedad: 15 años
Puntos: 1485
curiosidades de javascript

que tal comunidad!

¿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:
// 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);});
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.
Código:
[].forEach.call({"0":"string", "1":0, "2":true, "length":3}, function(v,k,o){console.log(arguments);});
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...
Código:
// notese la peculiaridad, la longitud es 8 y el indice 2 no esta definido ;
{"0":"string", "1":0, "3":true, "length":8};
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.
Código:
// 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);
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.

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!

__________________
la maldad es una virtud humana,
y la espiritualidad es la lucha del hombre contra su maldad.

Última edición por zerokilled; 08/04/2011 a las 09:37 Razón: par de errores en redaccion
  #2 (permalink)  
Antiguo 04/04/2011, 12:03
Avatar de _cronos2
Colaborador
 
Fecha de Ingreso: junio-2010
Mensajes: 2.062
Antigüedad: 13 años, 10 meses
Puntos: 310
Respuesta: curiosidades de javascript

No sé si a alguien le va a interesar pero yo lo pongo igual Resulta que ayer mientras desarrollaba un método para strings me topé con algo raro. Aaquí está el código:
Código Javascript:
Ver original
  1. String.extender({
  2.  'HexaRGB' : function(){
  3.   if(this.match(/\d{1,3}/g).length == 3){ return this }
  4.   var str = this;
  5.   str = str.replace('#', '');
  6.   if(str.length < 6){
  7.    var array = str.split('');
  8.    str = array[0] + array[0] + array[1] + array[1] + array[2] + array[2];
  9.   }
  10.   var colores = str.match(/\w{2}/g);
  11.   var rojo = parseInt(colores[0], 16), verde = parseInt(colores[1], 16), azul = parseInt(colores[2], 16);
  12.   return 'rgb(' + rojo + ', ' + verde + ', ' + azul + ')';
  13.  },
  14.  'RGBaHex' : function(){
  15.   if(/^#/.test(this)){ return this }
  16.   var str = this.match(/\d{1,3}/g);
  17.   return '#' + str[0].convertirRGB() + str[1].convertirRGB() + str[2].convertirRGB();
  18.  },
  19.  'convertirRGB' : function(){
  20.   var txt = "0123456789ABCDEF";
  21.   return txt.charAt((this - this % 16) / 16) + txt.charAt(this % 16);
  22.  }
  23. });
extender es un función que añade propiedades/métodos al prototipo. Total, que para hacer las pruebas a ver si funcionaba bien usé la consola de errores, y resulta que si tengo esto:
Código Javascript:
Ver original
  1. var string = '#F00'.HexaRGB(); // rgb(255, 0, 0)
  2. var texto = '0, 255, 0'.RGBaHex(); // #00FF00
Todo funciona bien. El problema llega aquí:
Código Javascript:
Ver original
  1. var string = '#F00'.RGBaHex(); // #F00
  2. var texto = '0, 255, 0'.HexaRGB(); // 0, 255, 0
Esto funciona si lo pongo dentro de la página, pero en la consola me devuelve [object Object] En Firebug e IE sí me decía por qué estaba compuesto el objeto pero como las pruebas las estaba haciendo con Chrome me di cuenta después XD así que hice esto:
Código Javascript:
Ver original
  1. JSPlus.escribir = function(obj){
  2.  switch(obj.constructor){
  3.   case String:
  4.    console.log(obj);
  5.   break;
  6.   case Object:
  7.    var str = '';
  8.    for(i in obj){
  9.     str += i + ' : ' + obj[i] + '\n';
  10.    }
  11.    console.log(str.replace(/\n$/, ''));
  12.   break;
  13.   case Array:
  14.    console.log(obj.split('\n'));
  15.   break;
  16.  }
  17.  return true;
  18. };
  19. JSPlus.ecribir('#F00'.RGBaHex());
Y resulta que me devuelve el objeto String que se crea para manipular el propio string. Devuelve algo como esto:
Cita:
0 : #
1 : F
2 : 0
3 : 0
HexaRGB : function()
RGBaHex : function()
convertirRGB : function()
__proto__ : Object
Así que la pregunta es, ¿por qué en la consola de errores devuelve el objeto String, mientras que en la página devuelve el string?
Saludos (:
PD: Mola la firma
__________________
" Getting older’s not been on my plans
but it’s never late, it’s never late enough for me to stay. "
Cigarettes - Russian Red
  #3 (permalink)  
Antiguo 04/04/2011, 12:58
Avatar de zerokilled
Javascripter
 
Fecha de Ingreso: abril-2009
Ubicación: Isla del Encanto, La Borinqueña [+>==]
Mensajes: 8.050
Antigüedad: 15 años
Puntos: 1485
Respuesta: curiosidades de javascript

que tal cronos!

en la observacion que haces, sucede por dos factores: todos los tipos de datos de javascript tiene un wrapper, y debido a que devuelves el valor this en el prototipo en la consola observaras que obtienes un objeto. el primer factor consiste en que automaticamente javascript envuelve los tipos de datos con un objeto de acuerdo a su tipo. por esa razon es posible invocar metodos directamente desde el valor aunque no se haya realizado estrictamente una instancia desde el constructor. me refiero por ejemplo,
Código:
"string".toUpperCase();
(new String("string")).toUpperCase();

(127).toString(16);
(new Number(127)).toString(16);
sin embargo, es naturaleza de javascript que al momento de imprimir el valor primitivo automaticamente invoca el metodo valueOf de ese wrapper. de modo que en lugar de mostrar el string [object Object] se imprime el valor. prueba a invocar el metodo valueOf cuando el string es devuelto como [object Object] y veras que obtienes el string real. en el caso de String, debe ser porque estas devolviendo el objeto en si (this). de todos modos, no es algo que sucede en todos los constructores, considera por ejemplo Number.

Código:
Object.prototype.that = function(){
return this;
};

console.log("string".that());
console.log("string".that().valueOf());

console.log((10).that()); // no muestra [object Object] ;
console.log((10).that().valueOf());
__________________
la maldad es una virtud humana,
y la espiritualidad es la lucha del hombre contra su maldad.
  #4 (permalink)  
Antiguo 04/04/2011, 13:35
Avatar de _cronos2
Colaborador
 
Fecha de Ingreso: junio-2010
Mensajes: 2.062
Antigüedad: 13 años, 10 meses
Puntos: 310
Respuesta: curiosidades de javascript

Sí, lo de que automáticamente convertía los strings a un objeto String lo leí en el libro de David Flanagan, pero lo que me llamó la atención es que la consola de errores me devolviera el objeto y no el string directamente sólo en ese caso. Aunque tiene cierto sentido porque después no devuelvo directamente this, sino que lo
modifico
Saludos (:
__________________
" Getting older’s not been on my plans
but it’s never late, it’s never late enough for me to stay. "
Cigarettes - Russian Red
  #5 (permalink)  
Antiguo 06/04/2011, 05:23
Avatar de masterpuppet
Software Craftsman
 
Fecha de Ingreso: enero-2008
Ubicación: Montevideo, Uruguay
Mensajes: 3.550
Antigüedad: 16 años, 3 meses
Puntos: 845
Respuesta: curiosidades de javascript

Buenas,

les dejo un link con varios ejemplos interesantes.

Saludos.
__________________
http://es.phptherightway.com/
thats us riders :)
  #6 (permalink)  
Antiguo 12/04/2011, 01:21
Avatar de zerokilled
Javascripter
 
Fecha de Ingreso: abril-2009
Ubicación: Isla del Encanto, La Borinqueña [+>==]
Mensajes: 8.050
Antigüedad: 15 años
Puntos: 1485
Respuesta: curiosidades de javascript

mientras leia un material de Node.js me encontre con este enlace interesante, http://wtfjs.com/. el autor comparte un ejemplo que me ha dejado perplejo y no comprendo por que. javascript con problema de identidad.
Cita:
Iniciado por http://wtfjs.com/2010/11/15/i-am-myself-but-also-not-myself
i am myself but also not myself
Sometimes JavaScript has identity crisis:
Código:
var foo = [0];
console.log(foo == !foo);
console.log(foo == foo);
Is it time to have a "maybe" operator?
Cita:
soy yo mismo pero tampoco lo soy
algunas veces javascript tiene crisis de identidad
Código:
var foo = [0];
console.log(foo == !foo);
console.log(foo == foo);
es momento de tener un operador "quizas"?
__________________
la maldad es una virtud humana,
y la espiritualidad es la lucha del hombre contra su maldad.
  #7 (permalink)  
Antiguo 12/04/2011, 10:02
Avatar de David
Moderador
 
Fecha de Ingreso: abril-2005
Ubicación: In this planet
Mensajes: 15.720
Antigüedad: 19 años
Puntos: 839
Respuesta: curiosidades de javascript

Buscando una explicación para esto último encontré que por una particularidad extraña el array vacío (o con un elemento que se evalúe como false) se evalúa como false pero al convertirlo explícitamente a Boolean se vuelve true:
Código Javascript:
Ver original
  1. console.log([] == false);
  2. console.log([0] == false);
  3. console.log([""] == false);
  4. console.log([null] == false);
  5. console.log([undefined] == false);
  6.  
  7. console.log(Boolean([]));
  8. console.log(Boolean([0]));
  9. console.log(Boolean([""]));
  10. console.log(Boolean([null]));
  11. console.log(Boolean([undefined]));
__________________
Por favor, antes de preguntar, revisa la Guía para realizar preguntas.
  #8 (permalink)  
Antiguo 12/04/2011, 11:42
Avatar de zerokilled
Javascripter
 
Fecha de Ingreso: abril-2009
Ubicación: Isla del Encanto, La Borinqueña [+>==]
Mensajes: 8.050
Antigüedad: 15 años
Puntos: 1485
Respuesta: curiosidades de javascript

mas o menos era la misma conclusion que habia llegado. lo mas confuso para mi fue que de antemano conocia que cualquier objeto convertido a boolean devuelve true, sin importar si esta vacio o no. pero en el caso de una comparacion, parece que el array sufre un proceso antes de finalmente convertirse en boolean. alguna vez tendre que leer la documentacion ECMAScript.
__________________
la maldad es una virtud humana,
y la espiritualidad es la lucha del hombre contra su maldad.
  #9 (permalink)  
Antiguo 12/04/2011, 11:44
 
Fecha de Ingreso: abril-2010
Ubicación: df
Mensajes: 26
Antigüedad: 14 años
Puntos: 9
Respuesta: curiosidades de javascript

Creo que deberían de checar http://wtfjs.com/ donde la mayoría se resumen a que js no usa una comparación de los objetos si no de sus apuntadores a memoria.

Por ejemplo
var a = new Array('a','b');
var b = new Array('a','b');
console.log(a==b);
//False
mientras que
var a = new Array('a','b');
var b = a;
console.log(a==b);
//True

Y esto se debe a que js se programo para los browsers antiguos que no tenían el poder de los actuales y se optimizaron muchas cosas para poderlos hacer eficientes.
  #10 (permalink)  
Antiguo 12/04/2011, 11:58
Avatar de Panino5001
Me alejo de Omelas
 
Fecha de Ingreso: mayo-2004
Ubicación: -34.637167,-58.462984
Mensajes: 5.148
Antigüedad: 20 años
Puntos: 834
Respuesta: curiosidades de javascript

En realidad no tiene que ver con apuntadores de memoria. Si fuera ése el caso, esto daría un resultado diferente:
Código PHP:
<script type="text/javascript">
var 
foo = [0];
var 
c=foo;
console.log(foo == !c);
console.log(foo == c);
</script> 
El tema tiene que ver con la conversión automática de tipos dependiendo del contexto. Una excelente explicación de esto la da Dmitry Baranovskiy aquí:
http://dmitry.baranovskiy.com/post/o...ascript-part-i
  #11 (permalink)  
Antiguo 12/04/2011, 12:26
Avatar de zerokilled
Javascripter
 
Fecha de Ingreso: abril-2009
Ubicación: Isla del Encanto, La Borinqueña [+>==]
Mensajes: 8.050
Antigüedad: 15 años
Puntos: 1485
Respuesta: curiosidades de javascript

@siedrix, ese caso es distinto porque, aunque con la misma estructuras, ambos son arrays. el segundo devuelve true porque b es una referencia de a. es lo mismo que sucede con los objetos y funciones.
Código:
console.log(function(){} == function(){});
console.log({} == {});
el caso que estoy mencionando es distinto a esto porque se esta comparando un objeto con un valor primitivo, en este caso un boolean. de hecho, mira lo que sucede en el siguiente ejemplo.
Código:
console.log([3] == 3); // true ;
console.log(["s"] == "s"); // true ;

// sin embargo ;
console.log([undefined] == undefined); // false ;
console.log([null] == null); // false ;
creo que la razon se debe a lo que se explica en este caso, http://wtfjs.com/2011/02/11/all-your...elong-to-Array. aparentemente tiene que ver con la conversion en ToPrimitive.
__________________
la maldad es una virtud humana,
y la espiritualidad es la lucha del hombre contra su maldad.
  #12 (permalink)  
Antiguo 11/06/2011, 01:40
Avatar de Panino5001
Me alejo de Omelas
 
Fecha de Ingreso: mayo-2004
Ubicación: -34.637167,-58.462984
Mensajes: 5.148
Antigüedad: 20 años
Puntos: 834
Respuesta: curiosidades de javascript

Un enlace que explica claramente el por qué de algunas "inconsistencias" de javascript:
http://javascriptweblog.wordpress.co...nd-javascript/

Otro enlace interesante es el de esta trivia de Dmitry Baranovskiy:
http://dmitry.baranovskiy.com/post/s...now-javascript
Y mucho más es la explicación de Nicholas C. Zakas:
http://www.nczonline.net/blog/2010/0...vascript-quiz/

Última edición por Panino5001; 11/06/2011 a las 01:49
  #13 (permalink)  
Antiguo 11/06/2011, 08:46
Avatar de Aijoona
Colaborador
 
Fecha de Ingreso: mayo-2011
Ubicación: Buenos Aires
Mensajes: 779
Antigüedad: 13 años
Puntos: 343
Respuesta: curiosidades de javascript

El blog a leer para entender muchas cosas 'extrañas' de JavaScript es el de @kangax (Juriy Zaytsev): Perfection kills.

Acá hay un quiz de ese mismo blog, vale la pena leer los comentarios.

Saludos.
__________________
blog | @aijoona

Etiquetas: curiosidades, oculto, rarezas
Atención: Estás leyendo un tema que no tiene actividad desde hace más de 6 MESES, te recomendamos abrir un Nuevo tema en lugar de responder al actual.
Respuesta

SíEste tema le ha gustado a 7 personas




La zona horaria es GMT -6. Ahora son las 13:44.