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.
functionisObject(subject){returntypeof subject =="object";}functionisArray(subject){returnArray.isArray(subject);}functionrequiredParam(param){thrownewError(param +" es obligatorio");}functioncreateStudent({ 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,},getname(){return privateAtributos["_name"];},setname(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 GETTERjuan.name="Rigoberto";// Se ejecuta el SETTERconsole.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);
Vamos a aprender ahora a identificar objetos. Primero, conozcamos acerca del Duck Typing. 🤔👨💻
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.
Muy buen callout, son una especie de interfaz, me di cuenta con esta clase que los habia entendido mal, viendolo como una interface ahora si ya lo tengo claro
Los miro como aquellos que adquieren algo para luego pasar a otras clases .
Respondiendo la pregunta del profe 😂 Según la RAE, caracter no existe, solo existe carácter, y hace referencia a varias definiciones, entre ellas, “Signo 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.
Existe carácter en singular y caracteres en plurar. Mucha gente se acostumbró a acentuar ambos como en el plural.
character, (carácter en ingles), tiene silaba tónica(acento para nosotros) en Ter, la programación es en su mayoría ingles así que debe venir de ahi
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 ={getprop(){returnthis.__prop__;},setprop(){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,getprop(){returnthis.__prop__;},setprop(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}
Genial
Getters y setters
getname(){returnprivate["_name"];},setname(newName){ newName.length!==0?private["_name"]= newName :console.warn("Name can't be empty");}
Me gusta la elegancia del operador ternario.
¡Se ve genial! :)
Hay una forma más simple de hacer lo visto en la clase anterior y es usar getters y setters:
Permiten hacer validaciones (al contrario de crear un atributo "name")
No creamos una propiedad 'name' por error (en vez de cambiar _name)
No hace falta que protejamos los getters y setters, la única forma de redefinir "name" 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.
La sintaxis get vincula una propiedad de objeto a una función que se llamará cuando se busque esa propiedad.
·
La sintaxis set vincula una propiedad de objeto a una función que se llamará cuando se intente establecer esa propiedad.
Muy útil! Solo tengan en cuenta que los links están intercambiados.
Veo que con setters y getters aun se puede editar el nombre sin restricciones si editamos el value en Object.defineProperty de juan y 'name', entonces aun es preferible de la forma del video anterior donde no existia el atributo name, o no?
Oh, ya entendi analizando mas el codigo note lo que pasa, en efecto se edita la propiedad name pero ese no es el nombre del usuario, ese atributo se mantiene intacto en private, y se edita un fake, grandioso!!, se explica en el ultimo par de minutos pero no lo habia entendido bien jajaja
De todas las personas que estan tomando este curso
Quiense sientes que si aprenden a usar estos metodos pero aun no saben como aplicarlos en un ejercicio
Me gustaria mucho talleres practicos para usar estos metodos por que asi siento que aprendo mas pero estube checando cursos futuros y creo que si hay muchos cursos practicos alquien sabe mas al respecto..
Espero comprender muy bien todos estos metodos aunque si los veo algo facil pero sin embargo no logro saber en que momentos y como usarlos en un proyecto de verdad
:) Hola! Estoy un poco confundida con los getters y setters y el valor fake que dice el profe. Para que sirve ese valor fake?
Y mi otra duda es que si podemos editar los setters y getters con Object.defineProperty ... que caso tiene tener los getters and setters si no me estan protegiendo la variable?
Imagina que tenemos un método llamado imprimirCertificado o generarDiploma. Y ese método llama a la propiedad private["_name"] para obtener el nombre de la persona para la que está generando el certificado.
.
Los getters y setters nos ayudan a que solo nuestros propios métodos y funciones tengan acceso a variables privadas. Si alguna otra función desde afuera intenta modificar nuestra variable privada, no va a poder, sino que va a pasar por las validaciones de nuestros getters y setters (sobre todo de los setters).
.
La única medio forma de cambiar esto es con Object.defineProperty. Si utilizamos este método para asignarle un value a nuestros setters, pos va a funcionar, cualquier función externa que quiera obtener la propiedad name va a obtener el valor "hackeado" con el defineProperty.
.
¡PERO! -- esto es lo importante
.
Aunque las funciones de afuera estén accediendo al valor hackeado, la función internamente no fue modificada. ¿Recuerdas que nuestro método imprimirCertificado accedía a private["_name"]? Pos ese sigue igual que antes. No pudo ser hackeado de ninguna manera. Los métodos internos de nuestra función (como el de generar diplomas) siguen teniendo el valor correcto de la variable privada name.
.
So, como recapitulación:
Los getters y setters protegen a nuestras variables privadas para que solo puedan ser actualizadas bajo ciertas validaciones
El valor de los getters y setters hacia AFUERA puede ser hackeado (alterado sin las validaciones) utilizando Object.defineProperty
Pero el valor de los getters y setters NO puede ser hackeado por DENTRO, nuestras variables privadas siguen sin ser modificadas, ni siquiera con Object.defineProperty
Recuerda que una cosa es el objeto de nuestras propiedades privadas y otra cosa completamente diferente es el objeto que retornamos en nuestra función, ahí está el truco :D
Muchisimas gracias por esa explicación tan genial! Ya me queda super claro!
Alguien sabe el error en mi codigo?
functioncreateNewCourse({ name =mandatory("name"), school, score =mandatory("score"), lang, freeAcces
}={}){constprivate={"_name": name
}constpublic={ school, score, lang, freeAcces,getname(){returnprivate["_name"];},setname(newName){if(newName.length!=0){private["_name"]= newName;}else{console.warn("nombre invalido, debes incluir al menos un caracter")}}}Object.freeze(public);Object.freeze(private);returnpublic;};// Funcion para crear cursoslet cursoMatematicas =createNewCourse({name:"Algebra",school:["Science"],freeAcces:false,score:10});// instancia del prototipo Courses que resulta de una funcionObject.defineProperty(cursoMatematicas,"name",{value:"Nuevo"})
Revisé tu código pero no le veo problemas. ¿Tienes algún error en la consola o tu código no está funcionando en algún caso en concreto que tal vez yo no esté considerando?
Usamos getters y setters para validar también que el cambio de nombre no tenga alguna palabra indebida.
const blackList =["nombreProhibido","nombreProhibido1","nombreProhibido2"]constpublic={getname(){returnprivate._name;},setname(newName){// validamos que el nombre tenga minimo 2 caracteres y no incluya alguna frase prohibidaif(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 'a' ponemos: '\u00E1' dentro de la cadena que vamos a imprimir en pantalla.
Entonces si hay una forma de editar el nombre, que es defineProperty, por ende, no es privado. Alguien que me corrija si no es así
Pero con el mismo defineProperty puedes definir que ni el mismo defineProperty pueda cambiarle el valor en el futuro. :wink:
Me confunde quien es el _name Private en el ejemplo, porque Roberto lo edito con Object.defineProperty cuantas veces quiera, osea Roberto es el fake cierto? entonces, quien es el Name Privado que no se altera? donde lo veo..
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
Control de Acceso
Los getters y setters actúan como guardianes de tus propiedades. Mientras el getter permite recuperar valores de forma controlada, el setter intercepta la asignación, permitiendo validar datos antes de que toquen el estado interno del objeto.
Encapsulamiento
Para proteger datos, usa la convención de guion bajo (_propiedad) para indicar que es privada. Esto obliga a usar tus métodos de acceso, garantizando que ningún dato inválido corrompa tu lógica interna.
entonces porque podemos modificar el valor del atributo name asignando le un Sting
juan.name='Roberto'
en este caso pasa por el set?
CONSULTA: ¿Solo personas que conozcan de la función Object.getOwnPropertyDescriptors si podrán modificar el valor de name?...Eso es que que entendí al final.
Hola!. Es mejor usar los métodos readName y changeName en lugar de gettes y setters?. Mi duda es debido a que se puede modificar con la propiedad value el método get y set, mientras que en readName y changeName no se puede.
Es recomendado los getter y setter, ya que genera una programación más limpia al momento de instanciar la clase y usar el objeto, además al usarse los métodos de getter y setter se pueden hacer validaciones, al igual que con los métodos readName y changeName