He estado tratando de entender los getters y setters y no se está hundiendo. He leído JavaScript Getters and Setters y Defining Getters and Setters y simplemente no lo .
¿Alguien puede decir claramente:
- Qué deben hacer un captador y un colocador, y
- ¿Da algunos ejemplos MUY simples?
javascript
setter
getter
Alexander Abakumov
fuente
fuente
a = setValue(5);
cona = 5;
ysetValue()
por ello se pondría bajo el capó para hacer lo que quiera.Respuestas:
Además de la respuesta de @ millimoose , los setters también se pueden usar para actualizar otros valores.
Ahora, se puede establecer
fullName
, yfirst
, ylast
se actualizará y viceversa.fuente
Object.defineProperty
función más nueva que puede definir captadores y definidores.this.__defineGetter__
laObject.defineProperty
función más nueva .Name.prototype.constructor
? Parece una mala alternativa a la respuesta de millimoose .Getters y Setters en JavaScript
Visión general
Los captadores y establecedores en JavaScript se utilizan para definir propiedades computadas o accesores . Una propiedad calculada es aquella que usa una función para obtener o establecer un valor de objeto. La teoría básica es hacer algo como esto:
Esto es útil para hacer cosas automáticamente detrás de escena cuando se accede a una propiedad, como mantener los números dentro del rango, formatear cadenas, desencadenar eventos de cambio de valor, actualizar datos relacionales, proporcionar acceso a propiedades privadas y más.
Los siguientes ejemplos muestran la sintaxis básica, aunque simplemente obtienen y establecen el valor del objeto interno sin hacer nada especial. En casos reales, modificaría el valor de entrada y / o salida para satisfacer sus necesidades, como se indicó anteriormente.
obtener / establecer palabras clave
ECMAScript 5 admite
get
yset
palabras clave para definir propiedades calculadas. Funcionan con todos los navegadores modernos, excepto IE 8 y versiones inferiores.Getters y Setters personalizados
get
yset
no son palabras reservadas, por lo que se pueden sobrecargar para crear sus propias funciones de propiedad computarizadas de navegador cruzado. Esto funcionará en cualquier navegador.O para un enfoque más compacto, se puede usar una sola función.
Evite hacer algo como esto, lo que puede conducir a la acumulación de código.
Para los ejemplos anteriores, los nombres de las propiedades internas se resumen con un guión bajo para disuadir a los usuarios de simplemente hacer
foo.bar
vs.foo.get( 'bar' )
y obtener un valor "sin cocinar". Puede usar código condicional para hacer cosas diferentes según el nombre de la propiedad a la que se accede (a través delname
parámetro).Object.defineProperty ()
Usar
Object.defineProperty()
es otra forma de agregar captadores y establecedores, y se puede usar en objetos después de que se hayan definido. También se puede usar para establecer comportamientos configurables y enumerables. Esta sintaxis también funciona con IE 8, pero desafortunadamente solo en objetos DOM.__defineGetter __ ()
Finalmente,
__defineGetter__()
es otra opción. Está en desuso, pero todavía se usa ampliamente en la web y, por lo tanto, es poco probable que desaparezca pronto. Funciona en todos los navegadores, excepto IE 10 y versiones inferiores. Aunque las otras opciones también funcionan bien en no IE, entonces esta no es tan útil.También vale la pena señalar que en los últimos ejemplos, los nombres internos deben ser diferentes a los nombres de acceso para evitar la recurrencia (es decir,
foo.bar
llamarfoo.get(bar)
llamarfoo.bar
llamar llamarfoo.get(bar)
...).Ver también
MDN get , set , Object.defineProperty () , __defineGetter __ () , __defineSetter __ ()
MSDN IE8 Getter Support
fuente
this[ '_' + name ] = value;
podría haberthis[ '_' + name ] = arguments[1];
y no habría necesidad de especificarvalue
arg.var foo = { bar : 123, get bar(){ return bar; }, set bar( value ){ this.bar = value; } }; foo.bar = 456;
genera una excepción: RangeError no capturado: el tamaño máximo de la pila de llamadas excedido en Object.set bar [como bar] (<anónimo>: 4: 32) en Object.set bar [como barra] (<anónimo>: 4: 32 ) en Object.set bar [como barra] (<anónimo>: 4: 32) en Object.set barra [como barra] (<anónimo>: 4: 32) en Object.set barra [como barra] (<anónimo> : 4: 32) en Object.set bar [como bar] (<anónimo>: 4: 32)bar: 123
ythis.bar = value
etc., cámbielos a,_bar
por ejemplo. Ver: hongkiat.com/blog/getters-setters-javascript_foo
omFoo
. Si es lo mismo que getter / setter, causará un bucle infinito debido a la recursión y luego un Stack Overflow ™ ;-) porque cuando dices a = b, llama a a.get (b) que a su vez llama a = b , que llama a.get (b), ...Los usaría, por ejemplo, para implementar propiedades calculadas.
Por ejemplo:
(CodePen)
fuente
Object.defineProperties
.Lamento resucitar una vieja pregunta, pero pensé que podría aportar un par de ejemplos muy básicos y explicaciones para tontos. Ninguna de las otras respuestas publicadas hasta ahora ilustra una sintaxis como el primer ejemplo de la guía MDN , que es lo más básico posible.
Adquiridor:
... iniciará sesión
John Smith
, por supuesto. Un captador se comporta como una propiedad de objeto variable, pero ofrece la flexibilidad de una función para calcular su valor devuelto sobre la marcha. Básicamente es una forma elegante de crear una función que no requiere () al llamar.Setter:
... iniciará sesión
New York
en la consola. Al igual que los getters, los setters se llaman con la misma sintaxis que establecer el valor de una propiedad de objeto, pero son otra forma elegante de llamar a una función sin ().Vea este jsfiddle para un ejemplo más completo, quizás más práctico. Pasar valores al setter del objeto desencadena la creación o población de otros elementos del objeto. Específicamente, en el ejemplo de jsfiddle, al pasar una matriz de números se le pide al colocador que calcule la media, la mediana, la moda y el rango; luego establece las propiedades del objeto para cada resultado.
fuente
maps.roll
como una propiedad en lugar del valormaps.roll()
de retorno. Es solo una preferencia.maps.roll()
Getters y setters realmente solo tienen sentido cuando tienes propiedades privadas de clases. Dado que Javascript realmente no tiene propiedades de clase privada como normalmente pensaría en lenguajes orientados a objetos, puede ser difícil de entender. Aquí hay un ejemplo de un objeto contador privado. Lo bueno de este objeto es que no se puede acceder a la variable interna "cuenta" desde fuera del objeto.
Si todavía está confundido, eche un vistazo al artículo de Crockford sobre Miembros privados en Javascript .
fuente
var baz = foo.bar
tener un conjunto completo de comportamiento oculto detrás de él. Me gustaría esperar que defoo.getBar()
, sin embargo.Creo que el primer artículo al que enlaza lo dice con bastante claridad:
El objetivo aquí es para encapsular y abstraer los campos permitiendo sólo el acceso a ellos a través de una
get()
oset()
método. De esta manera, puede almacenar el campo / datos internamente de la forma que desee, pero los componentes externos solo están lejos de su interfaz publicada. Esto le permite realizar cambios internos sin cambiar las interfaces externas, hacer alguna validación o verificación de errores dentro delset()
método, etc.fuente
Aunque a menudo estamos acostumbrados a ver objetos con propiedades públicas sin ningún control de acceso, JavaScript nos permite describir propiedades con precisión. De hecho, podemos usar descriptores para controlar cómo se puede acceder a una propiedad y qué lógica podemos aplicarle. Considere el siguiente ejemplo:
El resultado final:
fuente
Lo que es tan confuso al respecto ... los getters son funciones que se llaman cuando obtienes una propiedad, setters, cuando la configuras. ejemplo, si lo haces
Estás configurando la propiedad prop, si estás usando getters / setters, entonces se llamará a la función setter, con "abc" como argumento. La definición de la función setter dentro del objeto idealmente se vería así:
No estoy seguro de qué tan bien se implementa en todos los navegadores. Parece que Firefox también tiene una sintaxis alternativa, con métodos especiales ("mágicos") con doble subrayado. Como de costumbre, Internet Explorer no admite nada de esto.
fuente
Puede definir el método de instancia para la clase js, a través del prototipo del constructor.
El siguiente es el código de muestra:
Y, esto debería funcionar para cualquier navegador, también puede simplemente usar nodejs para ejecutar este código.
fuente
También estaba algo confundido por la explicación que leí , porque estaba tratando de agregar una propiedad a un prototipo existente que no escribí, por lo que reemplazar el prototipo parecía un enfoque incorrecto. Entonces, para la posteridad, así es como agregué una
last
propiedad aArray
:Muy ligeramente mejor que agregar una función en mi humilde opinión.
fuente
Si se refiere al concepto de accesores, entonces el objetivo simple es ocultar el almacenamiento subyacente de la manipulación arbitraria. El mecanismo más extremo para esto es
Si te estás refiriendo a la característica real de get / setter de JS, por ejemplo.
defineGetter
/defineSetter
, o{ get Foo() { /* code */ } }
bien, vale la pena señalar que en la mayoría de los motores modernos el uso posterior de esas propiedades será mucho más lento de lo que sería de otra manera. p.ej. comparar el rendimiento devs.
fuente
Tengo uno para ustedes, que puede ser un poco feo, pero se puede hacer en todas las plataformas.
de esta manera, cuando llamas
Si realmente quieres condimentar las cosas ... puedes insertar un tipo de verificación:
o vuélvase aún más loco con el código avanzado typeof check: type.of () en codingforums.com
fuente