Contenido

Curiosidad en Javascript

11 Mar

+ 19

Esta mañana Jorge Cárdenas me preguntaba si veía algo raro en este código. Y tras mucho buscar y probar no entiendo por que al modificar x[0] modificamos y[0]. ¿Alguna idea? ¿Javascript crea punteros en lugar de instancias de objetos?


var x=new Array('a','b','c');
var y=new Array('d','e','f');

alert( x );     // alert "a,b,c"
alert( y );     // alert "d,e,f"

y=x; // El meollo de la cuestión.

alert( x );     // alert "a,b,c"
alert( y );     // alert "a,b,c"

x[0]='_';

alert( x );     // alert "_,b,c"
alert( y );     // alert "_,b,c"

Hola, esto ocurre porque al igual que en java, en javascript se trabaja con la referencia de los objetos, no con su valor.

cuando tu haces

y=x;

no estas diciendo:
‘El valor de la variable x, en la posición de memoria 0×0001 se copia en la variable y, en la posición de memoria 0×0002′

sino que lo que haces es decirle:
‘La referencia asignada a la variable y es la misma referencia asignada a la variable x’

por tanto, cuando modificas x, modificas todas las variables que tienen asignada la misma referencia. No se trata de punteros (en C podriamos hacer aritmetica de punteros, con el valor de la dirección del mismo) pero a este nivel funciona de forma parecida.

Espero haber resultado de ayuda, un saludo y gracias por tu página que me está resultando muy util.

Coincido con Locke, es mas, si haces y[0]=’_'; tambien se modificaria x[0]

Esta curioso, entonces quieren decir que al igualar x con y, esta igualdad siempre estara presente

jejeje, gracias por postearlo, “soy tú fan!!”, “soy tú fan!!”…

volviendo al tema, jiji, lo que me viene a la cabeza, es que cuanto error-inintencional no habrá en todos los scripts del mundo mundial debido a ésta “pequeña falla”…

si el mismísimo, el único, el inigua…, ok, ok… Andrés Nieto, no se dió cuenta del error a primera vista, ¿que se espera de todo los demás?… bueno, excusando un poco a andrés, estaría bien señalar que me respondió después de alejarse de los brazos de morfeo [ tal cual doncella, como a eso de las 6:07am ] XD…

bueno, el caso es de que espero que alguien aporte como copiar “sanamente” un array en javascript,,, osea, sin código adicional, no sé, una función nata…

de antepie, mil gracias ;)!!

off-topic :: vieras puesto iim.vxk en vez de jorge cárdenas, google me tiene bien rastreadito así.

#4 La verdad es que no me di cuenta, pero ahora que lo veo tampoco lo entiendo… no es muy práctico.

Osea te quieres hacer una copia de un array para modificarlo y tener el original a salvo… ¿no es posible?

Se me ocurre que como solución temporal, y que, ojo! no me gusta nada. Se podrían crear los dos arrays a la vez con los mismos datos,… menuda chapuza….

Bueno, esto pasa porque cuando nosotros tenemos un arreglo, el valor del arreglo no contiene ningun valor, sino una posicion de memoria.

Para acceder a los valores reales del arreglo, usamos los subindices [0], [1], etc…

Al igualar “y” con “x”, lo que estas haciendo es asignarle la misma posicion de memoria a las 2 variables, por lo que si modificas una variable, realmente modificaras las 2; esto es algo que javascript heredo de su lenguaje padre C

Saludos, tienes un blog muy interesante

#5, exacto, el código puesto es de ejemplo, pero la cuestión es la misma ::

- copiar el valor de “x” a “y”
- mantener a “x” intacto - valor útil -
- trabajar / modificar con “y”

… pues sí no?, cualquier “solución” viene siendo chapuza, porque según la lógica de sentido común, al hacer “x=y”, se debería estar pasando el valor, no una referencia…

un lindo parche podría ser ::

var x=new Array(’a',’b',’c'), k, y=new Array();

for(k in x) y.push(x[k]);

no lo he testeado, pero tengo la ligera sensación de que podría pasar lo mismo…

de antebrazo, muchas gracias a todos por su tiempo ;)

#1 y #6, pués si no, tal como nos las olíamos todos, el valor se pasaba por referencia…

mis respetos para los que crearon el JS y para el lenguaje mismo, pero aveces sólo una cosa pasa por mi mente:: DuMbAsS JaVasCrOPt!¡

Es exactamente lo que dice #1. No sé nada de javascript, pero en python es igual:

>>> x = ['a','b','c']
>>> y = ['d','e','f']
>>> x = y
>>> x.append(’anieto2k’)
>>> y
['d', 'e', 'f', 'anieto2k']

A ver que os parece:


Array.prototype.copy = function(nuevo) {
   for (var x=0;x<this .length;x++) nuevo.push(this[x]);
};

var a = new Array('a','b','c');
var b = new Array();

alert(a); //a,b,c
alert(b); // vacio

a.copy(b); // copiamos

alert(a); // a,b,c
alert(b); // a,b,c

b[0] = '_'; //Reemplazamos

alert(a); // a,b,c
alert(b); // _,b,c

bingote!!, éso es lo que buscabamos desde un principio…

porque!!, porque!!, porque tenemos que hacer “cosas extrañas” para copiar un putísimo lindo array???

gracias ;)

Se llama Paradigma Orientado a Objetos.. :D

Coincido con iim.vkx.. es porque estamos trabajando con objetos.. por mucho que digamos variable (yo el primero) se trata de objetos con un constructor y un destructor. Los valores dentro de la estructura del objeto no deben estar nunca ‘al aire’. A veces se implementa una operación por defecto para la asignación, pero no siempre.

Me ha encantado este post.

Hoy me acostaré con la satisfacción de haber aprendido algo nuevo.


var a = [ 1, 2 ];
var b = [].concat(a);

Lamentablemente solo nos sirve para arrays unidimensionales :(

#16 :: jeje, yo también había pensado en el uso de la función concat() de los array-objects, pero no terminaba por convencerme del todo…

No me lo puedo creeeer!!! Gracias muchachos!! Me han salvado de otras 9 horas de trabajo infructuoso y rompedero de cabeza. Lo del [].concat() (#16) va perfecto y seguiré trasteando un poco mas lo del prototype.copy que se ve poderoso. Muchas gracias monstruos!

me encanta, hace las reflexiones que uno se hace y las contestaciones claras, gracias =)

Comentar

#

Me reservo el derecho de eliminar y/o modificar los comentarios que contengan lenguaje inapropiado, spam u otras conductas no apropiadas en una comunidad civilizada. Si tu comentario no aparece, puede ser que akismet lo haya capturado, cada día lo reviso y lo coloco en su lugar. Siento las molestias.


Cerrar
Enviar por Correo