I don\'t know how I\'ve missed this for so long. I\'ve been presuming private instance variables to work like this, but they don\'t. They\'re private (as in non-global), cer
Privates are expensive, avoid them if possible
Private doesn't exist. You can do one of two things to emulate this.
function makePrinter(word) {
return {
print: function () {
console.log(word)
}
}
}
Browser support for weakmaps is awful. You will probably need an emulation, I recommend 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)
}
}
}());
var Printer = {
constructor: function (word) {
this._word = word
},
print: function () {
console.log(this._word)
}
}
A slight modification to the code using this
will work. The correct instance of Printer.prototype.print
was not being instantiated for the a
object.
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
If you are willing to use ES2015 classes (I already answered it here, but repeating for the sake of convenience),
with ESNext, you can use Javascript private variables like this:
class Foo {
#bar = '';
constructor(val){
this.#bar = val;
}
otherFn(){
console.log(this.#bar);
}
}
Private field #bar is not accessible outside Foo class.
You're doing some wonky stuff with that closure. _word
needs to be declared in the Printer
function, not lost in anonymous-closure land:
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
This keeps _word
private, at the expense of creating a new print
function on every Printer
instance. To cut this cost, you expose _word
and use a single print
function on the prototype:
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
Does it really matter that _word
is exposed? Personally, I don't think so, especially given the _
prefix.