TypeScript soporta getters/setters como una forma de interceptar accesos a un miembro de un objeto. Esto le da una forma de tener un control más fino sobre cómo se accede a un miembro en cada objeto.
Convirtamos una clase simple para usar get y set. Primero, empecemos con un ejemplo sin getters y setters.
Aunque permitir que la gente establezca directamente el nombre completo al azar es bastante útil, también podemos querer imponer algunas restricciones cuando se establece el nombre completo.
En esta versión, añadimos un configurador que comprueba la longitud del nuevo Nombre para asegurarse de que es compatible con la longitud máxima de nuestro campo de base de datos de respaldo. Si no lo es, arrojamos un error notificando al código del cliente que algo salió mal.
Para preservar la funcionalidad existente, también añadimos un simple programa que recupera el nombre completo sin modificar.
const fullNameMaxLength =10;classEmployee{private_fullName: string;getfullName(): string {returnthis._fullName;}setfullName(newName: string){if(newName && newName.length> fullNameMaxLength){thrownewError("fullName has a max length of "+ fullNameMaxLength);}this._fullName= newName;}}let employee =newEmployee();employee.fullName="Bob Smith";if(employee.fullName){console.log(employee.fullName);}
Para probarnos a nosotros mismos que nuestro accesorio está comprobando ahora la longitud de los valores, podemos intentar asignar un nombre de más de 10 caracteres y verificar que obtenemos un error.
Un par de cosas a tener en cuenta sobre los accesorios:
Primero, los accessores requieren que el compilador dé como resultado ECMAScript 5 o superior. La bajada de nivel a ECMAScript 3 no está soportada. Segundo, los accesorios con un get y sin set se infieren automáticamente para ser de solo lectura. Esto es útil cuando se genera un archivo.d.ts a partir de su código, porque los usuarios de su propiedad pueden ver que no pueden cambiarlo.
Muy útil de verdad la explicación, en el curso de js profesional también lo explicaron pero con tu ejemplo ya me ha quedado clarísimo su uso. Gracias!
ósea básicamente con los get y set , no podemos modificar su estado o su valor definitivamente?
_(underscore) Es una simple convención que indica una variable privada.
Es bueno tener en cuenta que la mayoría de equipos que no trabajan con TypeScript, usan esta convención.
La mayoría de equipos que sí trabajan con TypeScript, no la usan, porque el indicador de acceso (private) es suficiente.
Okey, lo tendré en cuenta. Yo cambie el nombre del get & set porque pensé que _ era mucho.
Es mejor llamar a los métodos con el prefijo getId y setId:
export{};enumPhotoOrientation{Landscape,Portrait,Square,Panorama}// get y setclassPicture{// Propiedadesprivateid: number;privatetitle: string;privateorientation:PhotoOrientation;publicconstructor(id: number,title: string,orientation:PhotoOrientation){this.id= id;this.title= title;this.orientation= orientation;}getgetId(){returnthis.id;}setsetId(id: number){this.id= id;}getgetTitle(){returnthis.title;}setsetTitle(title: string){this.title= title;}getgetOrientation(){returnthis.orientation;}setsetOrientation(o:PhotoOrientation){this.orientation= o;}// ComportamientopublictoString(){return`[id: ${this.id},
title: ${this.title},
orientation: ${this.orientation}]`;}}classAlbum{privateid: number;privatetitle: string;privatepictures:Picture[];publicconstructor(id: number,title: string){this.id= id;this.title= title;this.pictures=[];}getgetId(){returnthis.id;}setsetId(id: number){this.id= id;}getgetTitle(){returnthis.title;}setsetTitle(t: string){this.title= t;}publicaddPicture(picture:Picture){this.pictures.push(picture);}}constalbum:Album=newAlbum(1,'Personal Pictures');constpicture:Picture=newPicture(1,'Platzi session',PhotoOrientation.Square);album.addPicture(picture);console.log('album', album);// Accediendo a los miembros publicosconsole.log('picture.id', picture.getId);// get id()picture.setId=100;// private, set id(100);picture.setTitle='Another title';// privatealbum.setTitle='Personal Activities';//privateconsole.log('album', album);
Es mas sencillo así para algunos que conocemos un poco de Java, ya que esa es la convención que se utiliza para nombrar métodos getters y setters además que dichos nombres son más significativos que simplemente nombrarlos igual que los atributos de la clase a la que hacen referencia.
export{};console.clear();enumPhotoOrientation{Landscape='Landscape',Portrait='Portrait',Square='Square',Panorama='Panorama',}// get y setclassPicture{private_id: number;private_title: string;private_orientation:PhotoOrientation;constructor(id: number,title: string,orientation:PhotoOrientation){this._id= id;this._title= title;this._orientation= orientation;}getid(): number {returnthis._id;}setid(id: number){this._id= id;}gettitle(): string {returnthis._title;}settitle(title: string){this._title= title;}getorientation():PhotoOrientation{returnthis._orientation;}setorientation(orientation:PhotoOrientation){this._orientation= orientation;}// ComportamientopublictoString(){return`[id: ${this.id}, title: ${this.title}, orientation: ${this.orientation}]`;}}classAlbum{ #id: number; #title: string; #pictures:Picture[]=[];constructor(id: number,title: string){this.#id= id;this.#title= title;// this.pictures = [];}getid(): number {returnthis.#id;}// set id(id: number) {// this.#id = id;// }gettitle(): string {returnthis.#title;}settitle(title: string){this.#title= title;}addPicture(picture:Picture){this.#pictures.push(picture);// this.pictures.push({...picture});}}constpicture:Picture=newPicture(100,'cool',PhotoOrientation.Square);const picture1 =newPicture(201,'korn',PhotoOrientation.Square);constalbum:Album=newAlbum(534,'Family');console.log(picture);console.log(picture1);album.addPicture(picture);album.addPicture(picture1);console.log('album', album);// Accediendo a los miembros publicos// picture.id = 100;picture.title='Another title';console.log('album', album);// console.log(album.id);picture.title='New title';
Modificadores de acceso.
Get(accesa) y Set(muta), Interceptar y controlar el acceso a los miembros privados del objeto. Son métodos de la clase para leer y cambiar los valores de los miembros privados. De que forma podemos acceder & mutar el valor en los miembros. Validación de los nuevos valores en los miembros.
ya, en caso que les pase que les de error por el EcmaScript, en su terminal escriban: tsc --target es6 src/clases-get-set.ts.
ya con esto se les solucionara el problema.
Thanks, lo tendré en cuenta.
¿Por qué se coloca un guion bajo a las variables privadas?
Eso es una forma de decirle a los programadores que una variable no se debe modificar. Es solo una convención, por lo que incluso podemos cambiar esa variable si así lo deseamos, no hay problema por parte del lenguaje, pero es una convención que el programador le hace a otros programadores que pueda que trabajen en el proyecto a futuro
Lo había visto y no tenía claro el porque usaban un guion bajo.
METODOS GET Y SET
TypeScript soporta los métodos accesores set y get como una forma de interceptar los accesos a los miembros privados de un objeto.
export{}enumPhotoOrientation{Landscape,Portrait,Square,Panorama}//Los moficadores de acceso get y set son metodos que nos permiten controlar//El acceso a cada uno de los miembrosclassPicture{ #id:number; #title:string; #orientation:PhotoOrientation;constructor(id:number,title:string,orientation:PhotoOrientation){this.#id= id;this.#title= title;this.#orientation= orientation;}//El nombre de una funcion accesora no debe coincidir con el nombre de un miembro//Podremos arreglar esto cambiando el nombre del miembro o el de la funciongetidH(){returnthis.#id;}setidH(id){this.#id= id;}gettitleT(){returnthis.#title}settitleT(title:string){this.#title= title;}getorientationO(){returnthis.#orientation;}setorientationO(o:PhotoOrientation){this.#orientation= o;}publictoString(){return`[id ${this.#id},
title: ${this.#title},
orientation: ${this.#orientation}]`;}}classAlbum{ #id:number; #title:string; #pictures:Picture[];publicconstructor(id:number, title:string){this.#id= id;this.#title= title;this.#pictures=[];}publicaddPicture(picture:Picture){this.#pictures.push(picture);}}const album:Album=newAlbum(1,'personal pictures');const picture:Picture=newPicture(1,'Platzi session',PhotoOrientation) album.addPicture(picture);console.log(album);//Cada vez que efectuamos un cambio accesando a los atributos de mi objeto heredado//Estamos aplicando por debajo los metodos get cuando solo solicitamos el valor//Y set cuando cambiamos el valor de el atributoconsole.log(picture.id)//get id() picture.id=100;//private, set id(100) picture.title='Otro titulo'; album.title='Personal Activities';console.log(album);
instale la extencion que dijo el profesor, pero aun me marca error en los datos privados #, porque sera¿?
Fijate en el tsconfig.json el atributo target que sea es6 o mayor!
{"compilerOptions":{"target":"es6"}}
Es por la configuración el arvhico json principal, debe estar a la versión actual (es6)
Entonces que logica tiene establecer estados como privados y añadiendo los getter y setter para luego modificarlos como si fueran publicos. Porque no simplemente dejarlos publicos?
El uso de Gettters y Setters es utilizado muchisimo en Programación Orientada a Objetos, de manera que para acceder a la propiedad del objeto es a tráves de esas dos funciones.
Es completamente nromal pensar que es mejor dejar las propiedades públicas, pero no es siempre bueno dejar que sea visible para todos de manera que hay propiedades y funcioes que solo se usarán de manera interna en la Clase.
Hola Jose, hablando con un amigo que usa hace mucho typescript me dijo que es algo como de usar cuando realizas alguna modificacion al valor que se envia al set antes de setearlo propiamente dicho.
Creo que una mejor manera de apreciar que sí estamos usando los métodos GET y SET es escribir un nombre diferente al del atributo, a pesar de haber usado el guión bajo.
Ejemplo:
getidPicture(){returnthis._id}setidPicture(id:number){this._id= id
}gettitlePicture(){returnthis._title}settitlePicture(title:string){this._title= title
}getorientationPicture(){returnthis._orientation}setorientationPicture(orientation:PhotoOrientation){this._orientation= orientation
}getidAlbum(){returnthis._id}setidAlbum(id:number){this._id= id
}gettitleAlbum(){returnthis._title}settitleAlbum(title:string){this._title= title
}
Al momento de escribir el nombre del objeto, no vamos a acceder al atributo, sino al método:
//* Estamos usando los métodos get y set y, no los atributos directamentepicture.idPicture=100picture.titlePicture='Another title'album.titleAlbum='Title for an album'console.table({album})
Interceptar un acceso a cualqueir miembro de la clase si éste es privado:
Getters & Setters.
Le dan un toque de accesibilidad, si es que es necesario, para poder acceder -> modificar -> retornar algo que se desee saber.
export{}enumPhotoOrientation{Landscape,Portrait,Square,Panorama,};classPicture{// propertiesprivate_id: number;private_title: string;private_orientation:PhotoOrientation;//constructorpublicconstructor(id: number,title: string,orientation:PhotoOrientation){this._id= id;this._title= title;this._orientation= orientation;}//PerformanceprivatetoString(){return`[id: ${this._id}, title: ${this._title}, orientation: ${this._orientation}]`}}classAlbum{private_id: string;private_title: string;private_pictures:Picture[];publicconstructor(id: string,title: string){this._id= id;this._title= title;this._pictures=[];}getid(){returnthis._id}setid(id: string){this._id= id}gettitle(){returnthis._title}settitle(t: string){this._title= t}getpicture(){returnthis._pictures}setpicture(pic:Picture[]){this._pictures= pic}publicaddPicture(picture:Picture){this._pictures.push(picture);}}letalbum:Album=newAlbum('stories-1','Photos of mine');constnewPic:Picture=newPicture(2,'my new pic!',PhotoOrientation.Panorama);constnew2Pic:Picture=newPicture(3,'my 2nd new pic!',PhotoOrientation.Portrait);constnew3Pic:Picture=newPicture(4,'my 3rd new pic!',PhotoOrientation.Portrait);album.addPicture(newPic);album.addPicture(new2Pic);album.addPicture(new3Pic);console.log('album -> ', album);
Metodos set y get: soporta los métodos accesores set y get como una forma de interceptar los accesos a los miembros privados de un objeto
classPerson{private_name:string
constructor()getname(){returnthis._name}setname(name: string){this._name= name
}}
En nuestro objeto de clase person hariamos
person.name
Existirá alguna manera de que los getters y setters sean dinámicos? Algo así como, primero verificar si existe la propiedad y si existe aplicar el getter o el setter
Pudieras hacer eso con un if statement...
¿Alguna forma de generar getters and setters de manera automática?
En NetBeans después de declarar las variables das click derecho, insertar y seleccionas la opción de getters and Setters y el automáticamente los genera.
Tienes que ser más descriptivo en lo que solicitas, empezando por el IDE, o editor, hay diferentes maneras de generar con snippets dependiendo de tu ambiente de desarrollo.
gente una pregunta, cual es la diferencia entre definir un clase con una propiedad privada a la cual le aplicamos un metodo get y set , a directamente definirla como publica?
Hola!
Esto simplemente es útil al momento de escribir código, si haces un atributo privado estás obligando a los desarrolladores a que usen forzosamente la lógica que definas para modificar un atributo y no puedan cambiarlos por cualquier valor que quieran.
En una función de get y set puedes poner validaciones que retornen un error cuando no se pasa el argumento adecuado, así facilitas el debugging y te proteges contra errores.
Eso es algo que pensé bastante también. Como dijo el profesor, es un interceptor, o sea que te permite parar a mitad de camino cualquier valor que le quieran mandar a la función y si le pones un condicional como if, lo puedes validar y si cumple se asignará, y si no, no. Interceptor es la palabra clave. Fue una super revelación cuando me dí cuenta.
Me pueden ayudar porfa con un ejemplo concreto en el que pueda entender bien por qué es útil poner getters y setters en vez de dejarlo público? Aún es confuso.
Hola,
Aquí hay una discusión que te puede ayudar.
@CarlosAlba Mil gracias!
private myclass: number | string
public myclass2: number | string
Saludos, si los objetos en TS se crean luego de consumir un servicio web, me resulta útil trabajar con get y set
Tiene sentido crear un setter para un array de datos?
Claro, se puede utilizar un setter para todas las propiedades de la clase sin importar su tipo de dato si es primitivo, arreglo, etc
Gracias, @darkjeda, entiendo, pero su implementación sería tan simple como un
set(value: []) { this.#_pictures = value; }
Nunca me ha convenido del todo esta manera de hacerlo con este tipo de dato. Siento que algo falta.
Por qué fue la única variable a la que no agregó _set _y get si lo estaba haciendo con todas las demás entonces?