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), certainly, but the variables are shared across instances. This led to some very confusing bugs.
I thought I was following the best practices implemented by some of the best libraries out there, but it seems I missed something.
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
I have looked at this post, but it doesn't describe a best practice for implementing private instance variables. (is this even the name of what I want?) Method and variable scoping of private and instance variables in JavaScript
I also looked at this post, but the use of the 'this' keyword is what I used to do. Because it doesn't obfuscate I was trying to avoid it. Is this really the only way? Implementing instance methods/variables in prototypal inheritance
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.