Getters y Setters en JavaScript: Protección y Validación de Propiedades

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

Resumen
  • La sintaxis get vincula la propiedad de un objeto con una función que se llamará cuando se busque esa propiedad. [1]
  • La sintaxis set vincula la propiedad de un objeto con una función que se llamará cuando se intente hacer una asignación a esa propiedad. [2]

Cómo funciona Get y Set en JavaScript

Los métodos readName y changeName creados anteriormente serán reemplazados por getters y setters:

  1. Eliminamos o comentamos las funciones readName y changeName, además de las encapsulaciones de estos métodos que hicimos con Object.defineProperty:

    function isObject(subject) { return typeof subject == "object"; } function isArray(subject) { return Array.isArray(subject); } function requiredParam(param) { throw new Error(param + " es obligatorio"); } function createStudent({ name = requiredParam("name"), email = requiredParam("email"), age, twitter, instagram, facebook, approvedCourses = [], learningPaths = [], } = {}) { const privateAtributos = { "_name": name, }; const publicAtributos = { email, age, approvedCourses, learningPaths, socialMedia: { twitter, instagram, facebook, }, // readName() { 👈👈 // return privateAtributos["_name"]; // }, // changeName(newName) { 👈👈 // privateAtributos["_name"] = newName; // }, }; // Object.defineProperty(publicAtributos, "readName", { 👈👈 // writable: false, // configurable: false, // }); // Object.defineProperty(publicAtributos, "changeName", { 👈👈 // writable: false, // configurable: false, // }); return publicAtributos; }
  2. Definimos el getter con el cual obtendremos el atributo “privado” name

    function isObject(subject) { return typeof subject == "object"; } function isArray(subject) { return Array.isArray(subject); } function requiredParam(param) { throw new Error(param + " es obligatorio"); } function createStudent({ name = requiredParam("name"), email = requiredParam("email"), age, twitter, instagram, facebook, approvedCourses = [], learningPaths = [], } = {}) { const privateAtributos = { "_name": name, }; const publicAtributos = { email, age, approvedCourses, learningPaths, socialMedia: { twitter, instagram, facebook, }, get name() { // 👈👈 return privateAtributos["_name"]; }, }; return publicAtributos; }
  3. Definimos setter con el cual podremos asignar valores a nuestro atributo ”privado” name:

    function isObject(subject) { return typeof subject == "object"; } function isArray(subject) { return Array.isArray(subject); } function requiredParam(param) { throw new Error(param + " es obligatorio"); } function createStudent({ name = requiredParam("name"), email = requiredParam("email"), age, twitter, instagram, facebook, approvedCourses = [], learningPaths = [], } = {}) { const privateAtributos = { "_name": name, }; const publicAtributos = { email, age, approvedCourses, learningPaths, socialMedia: { twitter, instagram, facebook, }, get name() { return privateAtributos["_name"]; }, set name(newName) { // 👈👈 privateAtributos["_name"] = newName; } }; return publicAtributos; }
  4. Agreguemos una pequeña validación para garantizar que al menos la asignación a name sea de al menos una letra y no sea un string vacío.

    function isObject(subject) { return typeof subject == "object"; } function isArray(subject) { return Array.isArray(subject); } function requiredParam(param) { throw new Error(param + " es obligatorio"); } function createStudent({ name = requiredParam("name"), email = requiredParam("email"), age, twitter, instagram, facebook, approvedCourses = [], learningPaths = [], } = {}) { const privateAtributos = { "_name": name, }; const publicAtributos = { email, age, approvedCourses, learningPaths, socialMedia: { twitter, instagram, facebook, }, get name() { return privateAtributos["_name"]; }, set name(newName) { if (newName.length != 0) { // 👈👈 privateAtributos["_name"] = newName; } else { console.warn("Tu nombre debe tener al menos 1 caracter"); } }, }; return publicAtributos; }

¡Listo! Ya podemos crear objetos y utilizar los getters y setters respectivos del atributo name:

const juan = createStudent({ email: "juanito@frijoles.co", name: "Juanito" }); console.log(juan.name); // Se ejecuta el GETTER juan.name = "Rigoberto"; // Se ejecuta el SETTER console.log(juan.name);

Apliquemos Object.getOwnPropertyDescriptors sobre nuestro objeto juan para visualizar la accesibilidad de sus atributos: el atributo name no tendrá las propiedades value y wriable como tal, en vez de eso nos aparecerán las funciones get y set. Observemos esto en la consola del navegador:

Object.getOwnPropertyDescriptors(juan);
El atributo name no posee la propiedad value y writable como tal, sino que tiene a los métodos get y set en su lugar

Vamos a aprender ahora a identificar objetos. Primero, conozcamos acerca del Duck Typing. 🤔👨‍💻

Fuentes:

[1] https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/set

[2] https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/set

Contribución creada por: Martín Álvarez (Platzi Contributor) con el aporte de Andrés Felipe Eslava Zuluaga.