Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Implementing private instance variables in Javascript

Tags:

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

like image 795
SimplGy Avatar asked Mar 05 '12 18:03

SimplGy


People also ask

How do you create private variables in JavaScript?

Alternatively, we may also use the “this” keyword to make method (function) calls to stick to the main method itself which thus makes the variables private. The main idea for using the “this” keyword is just to make things directly visible that is making methods directly accessible.

Can you make instance variables private?

Instance variables are encapsulated by using the private access modifier. Methods can be public or private, but they are usually public.

Are there private variables in JavaScript?

In its current state, there is no “direct” way to create a private variable in JavaScript.

How do you declare an instance variable in JavaScript?

An instance variable is just a property of an object, as Felix Kling said. You can't use props because that's referencing a global or local variable called props . What you want to access is the current value of props for the current component, stored in this.


1 Answers

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.

like image 127
Matt Ball Avatar answered Sep 21 '22 16:09

Matt Ball