No tienes acceso a esta clase

隆Contin煤a aprendiendo! 脷nete y comienza a potenciar tu carrera

Getters y setters

14/20
Recursos
  • 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 鈥減rivado鈥 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 鈥漰rivado鈥 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: "[email protected]", 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.

Aportes 15

Preguntas 9

Ordenar por:

驴Quieres ver m谩s aportes, preguntas y respuestas de la comunidad?

o inicia sesi贸n.

Respondiendo la pregunta del profe 馃槀 Seg煤n la RAE, caracter no existe, solo existe car谩cter, y hace referencia a varias definiciones, entre ellas, 鈥淪igno de escritura鈥:

Lo cual es raro porque la mayor铆a de personas lo pronuncian con acento en la e (incluy茅ndome), y car谩cter (para m铆) hace referencia al conjunto de cualidades que definen la forma de ser de un ser vivo鈥 Pero, para la RAE, ambas cosas se desprenden de la misma palabra, car谩cter.

Los Getters y setters son m茅todos de acceso, lo que significa que generalmente son una interfaz publica para cambiar miembros de las clases privadas.

GETTERS Y SETTERS

Utilizamos el m茅todo est谩tico del prototipo object getOwnPropertyDescriptor().
Una funci贸n obtiene un valor de una propiedad se le llama getter y una que setea(establece) un valor de una propiedad se le llama setter
Para crearlos simplemente necesitan los keywords get y set


const obj = {
    get prop(){
        return this.__prop__;
    },
    set prop() {
        this.__prop__ = value * 2 ;
    },
};
obj.prop = 12;

console.log(obj.prop); // 24

Se crea un objeto, con una 煤nica propiedad, tiene un getter y un setter. De esta manera cada vz que le establezcamos un alor a la propiedad, el valor se multiplicar谩 por 2.

se puede crear un accessor properties es e manera expl膰ita usando Object.defineProperty()

Object.defineProperty(obj,//objeto target
'prop', //nombre de la propiedad)
 {
    enumerable:true,
    configurable:true,
    get prop(){
        return this.__prop__;
    },
    set prop(value){
        this.__prop__ = value * 2;
    },
};

obj.prop = 12;
var atr = Object.getOwnProperyDescriptor(obj,'prop');
console.log(atr); // {value: 24, writable: true, enumerable: true, configurable: true}

Getters y setters

get name() {
  return private["_name"];
},
set name(newName) {
  newName.length !==0 ? private["_name"] = newName : console.warn("Name can't be empty");
}

Hay una forma m谩s simple de hacer lo visto en la clase anterior y es usar getters y setters:

  • cambiamos 鈥榬eadName鈥 por
get name(){
	return private._name
}
  • cambiamos 鈥榗hangeName鈥 por
set name(anotherName){
	if(true){ //ac谩 validamos
		private._name = anotherName
	}
}

Las ventajas son:

  • C贸digo reducido y m谩s limpio
  • Permiten hacer validaciones (al contrario de crear un atributo 鈥渘ame鈥)
  • No creamos una propiedad 鈥榥ame鈥 por error (en vez de cambiar _name)

No hace falta que protejamos los getters y setters, la 煤nica forma de redefinir 鈥渘ame鈥 es con Object.defineProperty. Esto elimina las funciones y crea un nuevo atributo name, que aunque no afecta a _name hace imposible acceder a 茅l.

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/set
La sintaxis get vincula una propiedad de objeto a una funci贸n que se llamar谩 cuando se busque esa propiedad.

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/get
La sintaxis set vincula una propiedad de objeto a una funci贸n que se llamar谩 cuando se intente establecer esa propiedad.

Usamos getters y setters para validar tambi茅n que el cambio de nombre no tenga alguna palabra indebida.

    const blackList = ["nombreProhibido", "nombreProhibido1", "nombreProhibido2"]

    const public = {
        get name(){
            return private._name;
        },
        set name(newName){
	// validamos que el nombre tenga minimo 2 caracteres y no incluya alguna frase prohibida
            if (newName.length <= 1 || blackList.includes(newName)){
                console.warn("No puedes colocar este nombre, intenta otro");
            } else {
                private._name = newName;
            }
        }

Para usar el acento en la 鈥榓鈥 ponemos: 鈥榎u00E1鈥 dentro de la cadena que vamos a imprimir en pantalla.

Que clase de magia oscura es esta :v 鈥 Es broma, excelente eso de Getters y Setters

Primera cosa que me gusta de JS contra otros lenguajes que si realmente parecen orientados a objetos

Mi resumen:

// ### Uso de get y set

function createStudent4({
    name,
    age
} = {}) {
    const privateAttributes = {
        "_name" : name,
    }
    const publicAttributes = {
        age,
        get name() { //en vez de los m茅todos readName y changeName
            return privateAttributes["_name"];
        },
        set name(newName) {
            if (newName.length != 0) { // 馃憟馃憟
                privateAttributes["_name"] = newName;
            } else {
                console.warn("Tu nombre debe tener al menos 1 caracter");
            }
        },
    }
    return publicAttributes;
}

const efrain = createStudent4({name : "efrain",age : 20});

console.log(efrain.name); // Se ejecuta el GETTER
efrain.name = "Rigoberto"; // Se ejecuta el SETTER
console.log(efrain.name);

//Si se usa Object.defineProperty si se podr谩 modificar el nombre

Object.defineProperty(efrain,"name",{
    value:"LOL"
})

console.log(efrain.name); //LOL

En mi caso escribi un array de nombres no permitidos y valide que newName no fuera ninguno de estos, asi:

get name() {
	return private['_name']
},
set name(newName){
	if(!noAcceptNames.some(item => item == newName)){
	private['_name'] = newName;
} 

A mi si me dar铆a pero gracia llamarme 鈥楯ota鈥 jaja

Los m茅todos que permiten acceder al valor de un atributo se denominan 鈥済etters鈥 (del verbo ingl茅s 鈥済et鈥, obtener) y los que fijan el valor de un atributo se denominan 鈥渟etters鈥 (del verbo ingl茅s 鈥渟et鈥, fijar).

Configurando el set name para que no pueda recibir un nombre vac铆o y tampoco acepte espacios en el nombre:

set _name(newName){
            newName.length == 0 ? console.warn('Tu nombre debe contener alg煤n car谩cter') : newName.split(' ').length > 1 ? console.warn('Tu nombre no puede tener espacios') : private._name = newName;
        }