ejemplos - Implementando variables de instancia privada en Javascript
javascript pdf (3)
Estás haciendo algo extraño con ese cierre. _word
debe declarar en la función de Printer
, no se pierde en la zona de cierre anónimo:
function Printer(word) {
var _word = word;
this.print = function () {
console.log(_word);
}
}
var a = new Printer("Alex");
var b = new Printer("Bob");
a.print(); //Prints Alex
b.print(); //Prints Bob
Esto mantiene la _word
privada, a costa de crear una nueva función de print
en cada instancia de la Printer
. Para reducir este costo, exponga _word
y use una sola función de print
en el prototipo:
function Printer(word) {
this._word = word;
}
Printer.prototype.print = function () {
console.log(this._word);
}
var a = new Printer("Alex");
var b = new Printer("Bob");
a.print(); //Prints Alex
b.print(); //Prints Bob
¿ Realmente importa que la _word
se exponga? Personalmente, no lo creo, especialmente dado el prefijo _
.
No sé cómo me he perdido esto durante tanto tiempo. He estado asumiendo que las variables de instancias privadas funcionan así, pero no lo hacen. Son privados (como en no globales), sin duda, pero las variables se comparten a través de instancias. Esto llevó a algunos errores muy confusos.
Pensé que estaba siguiendo las mejores prácticas implementadas por algunas de las mejores bibliotecas, pero parece que me he perdido algo.
var Printer = (function(){
var _word;
Printer = function(word){
_word = word;
}
_print = function(){
console.log(_word);
}
Printer.prototype = {
print: _print
}
return Printer;
})();
var a = new Printer("Alex");
var b = new Printer("Bob");
a.print(); //Prints Bob (!)
b.print(); //Prints Bob
He visto esta publicación, pero no describe una práctica recomendada para implementar variables de instancia privadas. (¿es este el nombre de lo que quiero?) Método y alcance de variables de variables privadas y de instancia en JavaScript
También miré esta publicación, pero el uso de la palabra clave ''this'' es lo que solía hacer. Porque no me confunde que estaba tratando de evitarlo. ¿Es esta realmente la única manera? Implementación de métodos / variables de instancia en herencia prototípica.
Una ligera modificación al código utilizando this
funcionará. La instancia correcta de Printer.prototype.print
no estaba siendo instanciada para a
objeto.
var Printer = (function(){
var _word;
Printer = function(word){
this._word = word;
}
_print = function(){
console.log(this._word);
}
Printer.prototype = {
print: _print
}
return Printer;
})();
var a = new Printer("Alex");
var b = new Printer("Bob");
a.print(); //Prints Alex
b.print(); //Prints Bob
Las privadas son caras, evítelas si es posible
Lo privado no existe. Puedes hacer una de dos cosas para emular esto.
- cierres
- Mapas débiles
Cierres
function makePrinter(word) {
return {
print: function () {
console.log(word)
}
}
}
WeakMap
El soporte del navegador para los weakmaps es horrible. Probablemente necesites una emulación, te recomiendo pd.Name
var Printer = (function () {
var privates = function (obj) {
var v = map.get(obj)
if (v === undefined) {
v = {}
map.set(obj, v)
}
return v
}, map = new WeakMap()
return {
constructor: function (word) {
privates(this).word = word
},
print: function () {
console.log(privates(this).word)
}
}
}());
Objetos sensatas
var Printer = {
constructor: function (word) {
this._word = word
},
print: function () {
console.log(this._word)
}
}