¿Cuál es el punto de usar métodos getter y setter? Qué hacen exactamente y cuáles son los beneficios. Traté de darles sentido, pero simplemente no lo entiendo y qué pasa con el guión bajo que se usa con los métodos anteriores. Alguien puede explicar me lo. Gracias.
Las propiedades de acceso proporcionan una forma de llamar a una función cuando se lee ( get ) o se escribe ( set ) una propiedad, aunque el código que lo hace utilice el acceso a la propiedad o la sintaxis de asignación. He aquí un ejemplo de un captador:
const example = { get random() { return Math.random(); } }; const r = example.random; console.log(r); Tenga en cuenta que no hay () en random en ese ejemplo, parece un acceso directo a la propiedad de datos. Pero, de hecho, es una llamada de función oculta.
Los setters funcionan de la misma manera, pero cuando asignas la propiedad en lugar de cuando la lees:
const example = { set something(value) { console.log(`setter called with ${value}`); } }; example.something = 42;Debido a que son llamadas a funciones, no se almacena ningún valor a menos que las funciones lo almacenen.
Hay algunas razones por las que es posible que desee tener propiedades de acceso en lugar de propiedades de datos estándar. Por ejemplo:
Aquí hay un ejemplo de una propiedad que solo puede establecer en un número:
class Example { #storedValue = 0; set value(value) { const type = typeof value; if (type !== "number") { throw new Error(`Value must be of type number, not ${type}`); } this.#storedValue = value; } get value() { return this.#storedValue; } } const e = new Example(); e.value = 42; console.log(e.value); // 42 e.value = "something"; // Throws errorEso utiliza la función de campos privados bastante nueva para almacenar el valor donde no se puede acceder desde fuera de la clase, por lo que debe pasar por la propiedad de acceso para llegar a él. Eso permite que la clase valide los valores que asignas.
Depende de cómo los uses.
Si el getter/setter solo lee/escribe el valor de un campo público (los campos son públicos de forma predeterminada), probablemente no sean realmente necesarios. Pero cuando está usando campos privados (es decir, protegiendo campos de la manipulación directa desde fuera de la clase), tiene que usar getters y setters para cambiar su valor.
Además, los getters y setters pueden tener algo más de lógica (saneamiento, comprobaciones de validez, actualizaciones adicionales en la clase, ...). Incluso puede tener propiedades, que solo se calculan en tiempo de ejecución y no están respaldadas por ningún campo.
Por supuesto que puedes lograr lo mismo con las funciones. Pero parece más natural acceder a algo que es una propiedad de un objeto por "sintaxis de campo" que a través de una función.
Vea el siguiente ejemplo: #firstname y #lastname son campos privados de la clase person, es decir, no puede acceder a p.#firstname . Por lo tanto, necesitamos las propiedades FirstName y LastName para manipularlas. El getter solo devuelve el valor del campo respectivo, pero el setter también verifica si el nombre es válido (aunque esa verificación específica puede no tener mucho sentido, es solo un ejemplo). Además, tenemos un getter adicional para FullName que devuelve una combinación de nombre y apellido.
class Person { #firstname; #lastname; get FirstName() { return this.#firstname; } set FirstName(fn) { if (!fn || fn.length < 3) throw "invalid first name" this.#firstname = fn; } get LastName() { return this.#lastname; } set LastName(ln) { if (!ln || ln.length < 3) throw "invalid last name" this.#lastname = ln; } get FullName() { return `${this.#firstname} ${this.#lastname}`; } constructor(fn, ln) { this.#firstname = fn; this.#lastname = ln; } } let p = new Person("John", "Doe"); //if you uncomment this, you will get a syntax error //p.#firstname = "Jane"; console.log(p.FirstName); console.log(p.LastName); p.FirstName = "Jane"; console.log(p.FullName); try { p.LastName = "D." } catch (e) { console.log(e); }