Abstracción y Encapsulamiento en JavaScript Sin Prototipos ni Clases
Clase 12 de 20 • Curso Intermedio de Programación Orientada a Objetos en JavaScript
Resumen
Aplicaremos la abstracción y encapsulamiento a nuestros objetos en JavaScript sin necesidad de utilizar prototipos ni clases. Emplearemos el deep copy para generar nuevos objetos a partir de un objeto base y los encapsularemos con ayuda de los métodos del superprototipo Object
tales como defineProperty
, seal
y freeze
.
Abstracción con deep copy en JavaScript
Vamos a crear un objeto base para un estudiante:
// OBJETO BASE
const studentBase = {
name: undefined,
email: undefined,
age: undefined,
approvedCourses: undefined,
learningPaths: undefined,
socialMedia: {
twitter: undefined,
instagram: undefined,
facebook: undefined,
},
};
Con esto podemos crear nuevos estudiantes generando copias a partir de este objeto literal studentBase
. Para ello emplearemos deep copy con recursividad:
function isObject(subject) {
return typeof subject == "object";
}
function isArray(subject) {
return Array.isArray(subject);
}
// FUNCIÓN RECURSIVA
function deepCopy(subject) {
let copySubject;
const subjectIsObject = isObject(subject);
const subjectIsArray = isArray(subject);
if (subjectIsArray) {
copySubject = [];
} else if (subjectIsObject) {
copySubject = {};
} else {
return subject;
}
for (key in subject) {
const keyIsObject = isObject(subject[key]);
if (keyIsObject) {
copySubject[key] = deepCopy(subject[key]);
} else {
if (subjectIsArray) {
copySubject.push(subject[key]);
} else {
copySubject[key] = subject[key];
}
}
}
return copySubject;
}
// OBJETO BASE
const studentBase = {
name: undefined,
email: undefined,
age: undefined,
approvedCourses: undefined,
learningPaths: undefined,
socialMedia: {
twitter: undefined,
instagram: undefined,
facebook: undefined,
},
};
// GENERANDO NUEVOS OBJETOS
const juan = deepCopy(studentBase);
const emma = deepCopy(studentBase);
Encapsulamiento de objetos con Object.defineProperty
Sabemos que con Object.defineProperty
es posible editar las propiedades writable
, enumerable
y configurable
de los atributos de un objeto. Con esto limitamos el acceso a los datos de los nuevos objetos que generemos.
Editemos la propiedad configurable
del atributo name
del objeto juan
para evitar que sea borrada:
Object.defineProperty(juan, "name", {
value: "Juanito", // Definimos el valor del atributo "name" como "Juanito"
configurable: false
});
// El resto de propiedades (writable y enumerable) por defecto serán true
// Si intentamos borrar el atributo "name" ...
delete juan.name
// Observamos que no fue eliminado dicho atributo, pues bloqueamos su eliminación
console.log(juan);
/* > Mensaje en consola
{
name: 'Juanito',
email: undefined,
age: undefined,
approvedCourses: undefined,
learningPaths: undefined,
socialMedia: { twitter: undefined, instagram: undefined, facebook: undefined }
}
*/
Object.seal para restringir la eliminación de atributos
Seguramente deseemos tener esta configuración con el resto de nuestros atributos y así evitar que sean borradas, pero tendríamos que hacerlo uno por uno. Podemos simplificar esta labor utilizando Object.seal
:
Object.seal(juan); // Ahora todos los atributos están restringidos a que sean eliminados
Verificar si no se pueden borrar los atributos de un objeto
Con Object.isSealed
podemos comprobar si todas las propiedades de un objeto están bloqueadas a que sean eliminadas. Nos devolverán un booleano.
Object.isSealed(juan);
Verificar si los atributos de un objeto no pueden ser borradas ni editadas
Empleamos Objcet.isFrozen
para preguntar si las propiedades de un objeto están restringidas a su eliminación y edición. Devolverá un booleano.
Object.isFrozen(juan);

Contribución creada por: Martín Álvarez (Platzi Contributor) con el aporte de Javier Salcedo Salgado.