setters que property profundización getters and javascript setter getter

que - Javascript getters y setters para dummies?



que es getter y setter (13)

Getters y Setters en JavaScript

Visión de conjunto

Los getters y setters en JavaScript se usan para definir propiedades calculadas , o accesadores . 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:

var user = { /* ... object with getters and setters ... */ }; user.phone = ''+1 (123) 456-7890''; // updates a database console.log( user.areaCode ); // displays ''123'' console.log( user.area ); // displays ''Anytown, USA''

Esto es útil para hacer cosas detrás de escena automáticamente cuando se accede a una propiedad, como mantener los números dentro del rango, reformatear cadenas, desencadenar eventos de valor modificado, actualizar datos relacionales, proporcionar acceso a propiedades privadas, y más.

Los ejemplos a continuación muestran la sintaxis básica, aunque simplemente obtienen y configuran el valor del objeto interno sin hacer nada especial. En casos del mundo real, usted modificaría el valor de entrada y / o salida para satisfacer sus necesidades, como se indicó anteriormente.

obtener / configurar palabras clave

ECMAScript 5 admite get y set palabras clave para definir propiedades calculadas. Funcionan con todos los navegadores modernos, excepto IE 8 y siguientes.

var foo = { bar : 123, get bar(){ return bar; }, set bar( value ){ this.bar = value; } }; foo.bar = 456; var gaz = foo.bar;

Getters y Setters personalizados

get y set no son palabras reservadas, por lo que pueden sobrecargarse para crear sus propias funciones de propiedad calculadas a través del navegador. Esto funcionará en cualquier navegador.

var foo = { _bar : 123, get : function( name ){ return this[ ''_'' + name ]; }, set : function( name, value ){ this[ ''_'' + name ] = value; } }; foo.set( ''bar'', 456 ); var gaz = foo.get( ''bar'' );

O para un enfoque más compacto, se puede usar una sola función.

var foo = { _bar : 123, value : function( name /*, value */ ){ if( arguments.length < 2 ){ return this[ ''_'' + name ]; } this[ ''_'' + name ] = value; } }; foo.value( ''bar'', 456 ); var gaz = foo.value( ''bar'' );

Evite hacer algo como esto, lo que puede llevar a la inflamación del código.

var foo = { _a : 123, _b : 456, _c : 789, getA : function(){ return this.bar; }, getB : ..., getC : ..., setA : ..., setB : ..., setC : ... };

Para los ejemplos anteriores, los nombres de propiedad internos se abstraen con un guión bajo para desalentar a los usuarios de simplemente hacer foo.bar vs. foo.get( ''bar'' ) y obtener un valor "sin cocinar". Puede usar el código condicional para hacer cosas diferentes dependiendo del nombre de la propiedad a la que se accede (a través del parámetro de name ).

Object.defineProperty ()

El uso de Object.defineProperty() es otra forma de agregar getters y setters, y puede usarse en objetos una vez definidos. 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.

var foo = { bar : 123 }; Object.defineProperty( foo, ''bar'', { get : function(){ return bar; }, set : function( value ){ this.bar = value; } } ); foo.bar = 456; var gaz = foo.bar;

__defineGetter __ ()

Finalmente, __defineGetter__() es otra opción. Está obsoleto, pero aún 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 siguientes. Aunque las otras opciones también funcionan bien en no IE, entonces esta no es tan útil.

var foo = { bar : 123; } foo.__defineGetter__( ''bar'', function(){ return this.bar; } ); foo.__defineSetter__( ''bar'', function( value ){ this.bar = value; } );

Ver también

MDN get , set , Object.defineProperty() , __defineGetter__() , __defineSetter__()
Compatibilidad con MSDN IE8 Getter

He estado tratando de entender a los getters y setters y no se está hundiendo. He leído Getters y Setters de JavaScript y Definting Getters and Setters y simplemente no lo entiendo.

¿Alguien puede decir claramente:

  1. Qué se supone que deben hacer un getter y un setter, y
  2. ¿Dar algunos ejemplos MUY simples?

Además de la respuesta de @Si, los setters también se pueden usar para actualizar otros valores.

function Name(first, last) { this.first = first; this.last = last; } Name.prototype = { get fullName() { return this.first + " " + this.last; }, set fullName(name) { var names = name.split(" "); this.first = names[0]; this.last = names[1]; } };

Ahora puede establecer fullName , y el first y el last se actualizarán y viceversa.


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 aplicar a ella. Considere el siguiente ejemplo:

var employee = { first: "Boris", last: "Sergeev", get fullName() { return this.first + " " + this.last; }, set fullName(value) { var parts = value.toString().split(" "); this.first = parts[0] || ""; this.last = parts[1] || ""; }, email: "[email protected]" };

El resultado final:

console.log(employee.fullName); //Boris Sergeev employee.fullName = "Alex Makarenko"; console.log(employee.first);//Alex console.log(employee.last);//Makarenko console.log(employee.fullName);//Alex Makarenko


Creo que el primer artículo que enlazas dice claramente:

La ventaja obvia de escribir JavaScript de esta manera es que puede usar valores oscuros a los que no desea que el usuario acceda directamente.

El objetivo aquí es encapsular y abstraer los campos solo permitiendo el acceso a ellos a través de un método get () o set (). De esta forma, puede almacenar el campo / datos internamente de la forma que desee, pero los componentes externos están solo fuera de su interfaz publicada. Esto le permite realizar cambios internos sin cambiar las interfaces externas, realizar alguna validación o comprobación de errores dentro del método set (), etc.


Getters y setters realmente solo tienen sentido cuando tienes propiedades privadas de clases. Dado que Javascript realmente no tiene propiedades de clase privadas, como normalmente pensarías en los 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 "conteo" desde fuera del objeto.

var counter = function() { var count = 0; this.inc = function() { count++; }; this.getCount = function() { return count; }; }; var i = new Counter(); i.inc(); i.inc(); // writes "2" to the document document.write( i.getCount());

Si todavía está confundido, eche un vistazo al artículo de Crockford sobre Miembros Privados en Javascript .


Lo que es tan confuso al respecto ... getters son funciones que se invocan cuando se obtiene una propiedad, setters, cuando se establece. ejemplo, si lo haces

obj.prop = "abc";

Está configurando el elemento de propiedad, si usa 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 ideal sería algo como esto:

set prop(var) { // do stuff with var... }

No estoy seguro de qué tan bien se implemente en los navegadores. Parece que Firefox también tiene una sintaxis alternativa, con métodos especiales de doble subrayado ("magia"). Como es habitual, Internet Explorer no admite nada de esto.


Los usarías, por ejemplo, para implementar propiedades calculadas.

Por ejemplo:

function Circle(radius) { this.radius = radius; } Object.defineProperty(Circle.prototype, ''circumference'', { get: function() { return 2*Math.PI*this.radius; } }); Object.defineProperty(Circle.prototype, ''area'', { get: function() { return Math.PI*this.radius*this.radius; } }); c = new Circle(10); console.log(c.area); // Should output 314.159 console.log(c.circumference); // Should output 62.832

(CodePen)



Perdón por resucitar una vieja pregunta, pero pensé que podría contribuir con un par de ejemplos muy básicos y explicaciones para tontos. Ninguna de las otras respuestas publicadas hasta ahora ilustran la sintaxis como el primer ejemplo de la Object.defineProperties , que es lo más básico que uno puede obtener.

Adquiridor:

var settings = { firstname: ''John'', lastname: ''Smith'', get fullname() { return this.firstname + '' '' + this.lastname; } }; console.log(settings.fullname);

... registrará a John Smith , por supuesto. Un getter 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:

var address = { set raw(what) { var loc = what.split(//s*;/s*/), area = loc[1].split(/,?/s+(/w{2})/s+(?=/d{5})/); this.street = loc[0]; this.city = area[0]; this.state = area[1]; this.zip = area[2]; } }; address.raw = ''123 Lexington Ave; New York NY 10001''; console.log(address.city);

... registrará New York a la consola. Al igual que los getters, los setters son llamados con la misma sintaxis que con el valor de la propiedad de un objeto, pero son otra forma elegante de invocar una función sin ().

Vea este jsfiddle para un ejemplo más completo, tal vez más práctico. Al pasar valores al setter del objeto se desencadena la creación o población de otros objetos. Específicamente, en el ejemplo de jsfiddle, al pasar una matriz de números, se solicita al colocador que calcule la media, la mediana, el modo y el rango; luego establece las propiedades del objeto para cada resultado.


Puede definir el método de instancia para la clase js, a través del prototipo del constructor.

A continuación está el código de muestra:

// BaseClass var BaseClass = function(name) { // instance property this.name = name; }; // instance method BaseClass.prototype.getName = function() { return this.name; }; BaseClass.prototype.setName = function(name) { return this.name = name; }; // test - start function test() { var b1 = new BaseClass("b1"); var b2 = new BaseClass("b2"); console.log(b1.getName()); console.log(b2.getName()); b1.setName("b1_new"); console.log(b1.getName()); console.log(b2.getName()); } test(); // test - end

Y, esto debería funcionar para cualquier navegador, también puedes usar nodejs para ejecutar este código.


Si se refiere al concepto de acceso, entonces el objetivo simple es ocultar el almacenamiento subyacente de la manipulación arbitraria. El mecanismo más extremo para esto es

function Foo(someValue) { this.getValue = function() { return someValue; } return this; } var myFoo = new Foo(5); /* We can read someValue through getValue(), but there is no mechanism * to modify it -- hurrah, we have achieved encapsulation! */ myFoo.getValue();

Si te estás refiriendo a la característica real getter / setter de JS, ej. defineGetter / defineSetter , o { get Foo() { /* code */ } } , entonces 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 de

var a = { getValue: function(){ return 5; }; } for (var i = 0; i < 100000; i++) a.getValue();

vs.

var a = { get value(){ return 5; }; } for (var i = 0; i < 100000; i++) a.value;


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 me pareció un enfoque equivocado. Entonces, para la posteridad, así es como agregué una last propiedad a Array :

Object.defineProperty(Array.prototype, "last", { get: function() { return this[this.length - 1] } });

Siempre tan ligeramente mejor que agregar una función en mi humilde opinión.


Tengo uno para ustedes que podría ser un poco feo, pero se hace en todas las plataformas

function myFunc () { var _myAttribute = "default"; this.myAttribute = function() { if (arguments.length > 0) _myAttribute = arguments[0]; return _myAttribute; } }

de esta manera, cuando llamas

var test = new myFunc(); test.myAttribute(); //-> "default" test.myAttribute("ok"); //-> "ok" test.myAttribute(); //-> "ok"

Si realmente quieres condimentar las cosas ... puedes insertar un tipo de cheque:

if (arguments.length > 0 && typeof arguments[0] == "boolean") _myAttribute = arguments[0]; if (arguments.length > 0 && typeof arguments[0] == "number") _myAttribute = arguments[0]; if (arguments.length > 0 && typeof arguments[0] == "string") _myAttribute = arguments[0];

o vaya aún más loco con el tipo avanzado de cheque: tipo de código () en codingforums.com