Recursividad en JavaScript: Implementación de Deep Copy

Clase 9 de 20Curso Intermedio de Programación Orientada a Objetos en JavaScript

Resumen

Con el Deep Copy podemos generar copias de objetos sin importar que estos posean objetos anidados o métodos dentro.

Aplicando Deep Copy en JavaScript

Veamos el siguiente ejemplo:

<// OBJETO ORIGINAL const studentBase = { name: undefined, email: undefined, age: undefined, approvedCourses: undefined, learningPaths: undefined, socialMedia: { twitter: undefined, instagram: undefined, facebook: undefined, }, hello() { console.log("Hello, World!"); } }; // FUNCIÓN RECURSIVA function isObject(subject) { // Comprueba si es un objeto return typeof subject == "object"; // Devuelve true o false } function isArray(subject) { // Comprueba si es una Array return Array.isArray(subject); // Devuelve true o false } // FUNCIÓN RECURSIVA // Recibe un parametro que puede ser un objeto, array u otro tipo de dato function deepCopy(subject) { let copySubject; // Esta variable se convertira en array, objeto u otro tipo de dato const subjectIsObject = isObject(subject); // ¿El parámetro es objeto? const subjectIsArray = isArray(subject); // ¿El parámetro es array? if (subjectIsArray) { // Si es array... copySubject = []; // Asignamos un array vacío donde iremos copiando 1 a 1 los datos } else if (subjectIsObject) { // Si es un objeto... copySubject = {}; // Asignamosun objeto vacío donde iremos copiando 1 a 1 los atributos } else { // Sino es array u objeto... // Entonces es un tipo de dato que se puede copiar sin problemas, retornamos dicho // dicho dato y terminamos con la ejecución de la fucnción. return subject; } // Continuamos con la ejecución de la función si el parámetro fue array u objeto: for (key in subject) { // Recorremos cada uno de los atributos o datos del objeto o array // Comprueba si hay un objeto dentro del índice o atributo: const keyIsObject = isObject(subject[key]); if (keyIsObject) { // Si es verdad que hay un objeto dentro... // Invocamos recursivamente la misma función: copySubject[key] = deepCopy(subject[key]); // 👀🔄 } else { // Sino... if (subjectIsArray) { // Si el parámetro recibido por la función deepCopy es Array... // Agregamos el elemento a la variable a retornar al final de la función: copySubject.push(subject[key]); } else { // sino, significa que es objeto el parámetro y además no hay objetos anidados // en el elemento actual dentro del recorrido del bucle for, por tanto, asignamos // dicho elemento como valor a la propiedad correspondiente: copySubject[key] = subject[key]; } } } return copySubject; // Finalmente retornamos el objeto/array copia }>

Generemos un objeto copia utilizando la función recursiva e intentemos realizar modificaciones en el objeto copia y original:

<// OBJETO COPIA const juan = deepCopy(studentBase); // MODIFICACIONES EN EL OBJETO ORIGINAL studentBase.socialMedia.twitter = "@student_twitter" // MODIFICACIONES EN EL OBJETO COPIA juan.socialMedia.instagram = "@juanDC" // VEAMOS EN CONSOLA LAS DIFERENCIAS DEL OBJETO ORIGINAL Y LA COPIA console.log(studentBase); console.log(juan); // Mensaje en consola { name: undefined, email: undefined, age: undefined, approvedCourses: undefined, learningPaths: undefined, socialMedia: { twitter: '@student_twitter', 👈👈 👀 instagram: undefined, facebook: undefined }, hello: [Function: hello] 👈👈 FUNCIÓN } { name: undefined, email: undefined, age: undefined, approvedCourses: undefined, learningPaths: undefined, socialMedia: { twitter: undefined, instagram: '@juanDC', 👈👈 👀 facebook: undefined }, hello: [Function: hello] 👈👈 FUNCIÓN } >

Podemos notar que los cambios en un objeto no afecta en los valores de las propiedades del otro. Logramos crear una copia de un objeto que no esté condicionada a que si el objeto original tiene objetos anidados o si tiene métodos dentro.

Conozcamos ahora cómo emplear la abstracción en JavaScript con simplemente objetos, es decir, sin utilizar clases. 🤔🚀

Contribución creada por: Martín Álvarez (Platzi Contributor)