Scriptia. Javascript y buenas prácticas en español



Scriptia / artículos / Copia de arrays y objetos

Copia de arrays y objetos

Saltar a Anotaciones relacionadas

Cuando utilizamos operador de asignación (más comunmente conocido como `=`) para asignar un array –o un objeto– ya existente a una variable debemos tener en cuenta que no estamos almacenando una copia del array, sino una referencia al mismo.

Considérese:

var a = [ 1, 2, 3 ];
alert(a); // [ 1, 2, 3 ]
var b = a;
alert(b); // [ 1, 2, 3 ]
b.push(4);
alert(b); // [1, 2, 3, 4 ]
alert(a); // [ 1, 2, 3, 4 ] <-- `a` ha sido modificado indirectamente

Veamos como realizar una copia en lugar de almacenar una referencia.

Cocinaremos una función que nos permita copiar cualquier tipo de variable. Sabemos –o deberíamos saber– que:

* Al realizar una asignación de un tipo primitivo (`String`, `Number` y `Boolean`) la copia se realiza sola. Lo mismo sucede con los valores «especiales» `null` y `undefined`.
* Al realizar una asignación de un objeto (incluido un array, que no es sino un objeto _especializado_), no se realiza una copia sino que se asigna una referencia.

Por tanto, para _copiar_ un objeto, necesitamos recorrer sus entrañas y realizar asignaciones de sus métodos y propiedades si estos son primitivos. He aquí mi solución, seguida de algunas notas.

function copy(o) {
	if (typeof o != "object" || o === null) return o;
	var r = o.constructor == Array ? [] : {};
	for (var i in o) {
		r[i] = copy(o[i]);
	}
	return r;
}

Retomemos el ejemplo anterior, usando la función `copy` en lugar de un triste y solitario operador de asignación:

var a = [ 1, 2, 3 ];
alert(a); // [ 1, 2, 3 ]
var b = copy(a);
alert(b); // [ 1, 2, 3 ]
b.push(4);
alert(b); // [1, 2, 3, 4 ]
alert(a); // [ 1, 2, 3 ] <-- `a` permanece impasible

## Notas

1. El operador `typeof` devuelve la cadena “object” cuando trata con arrays, objetos y `null`.
2. Para distinguir un array de otros tipos de objetos, _debemos_ recurrir a su propiedad `constructor`.
3. Si no has _sobrecargado_ la clase predefinida `Array`, es posible iterar sobre los elementos de cualquier array con un `for (var i in o)` con toda la tranquilidad del mundo. Si lo has hecho, arrepiéntete, pecador: no es una buena idea.
4. Si sabes que lo que vas a copiar es una cadena, un número o un booleano, pasa de la función. El operador de asignación es más que suficiente.



Publicidad

Un comentario RSS

1 choan (2007-03-09 @ 10:56 pm):

Otra forma de copiar arrays, breve y chula:

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

Lamentablemente solo nos sirve para arrays unidimensionales :(


Di la tuya

Puedes usar estas etiquetas HTML: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> . Por favor, evita el abuso de las mayúsculas y cuida la ortografía.


Acerca de Scriptia

Saltar a la caja de búsqueda

Scriptia forma parte del PDM de Choan C. Gálvez, desarrollador web residente en Barcelona. Scriptia pretende mejorar la calidad de la documentación acerca de javascript disponible en español.