6

I'm currently looking into different patterns for building classes in JavaScript. But no matther what pattern I see, there are still some things I am not really sure about.

var ItemManager = (function()
{
    var p = function()
    {
        this.items= [];
    };

    p.prototype.addItem = function(item)
    {
        var self = this;    
        self.items.push(item);
    };

    return p;
}());

I create the simple class ItemManager, this class got the function addItem for adding any item to the collection. Now I don't really want the variable items, which represents the collection, to be public, this variable should be private, but I don't see any possible way to use a prototyped method to access private variables.

So what's the best practice in this case? Simply don't use private variables?

GoldenerAal
  • 91
  • 1
  • 2

3 Answers3

6
var ItemManager = function() {
    var items = [];

    return {
           addItem : function(item) {   
               items.push(item);
           },
           removeItem : function() {
                return items.pop();
           }
     }
};

var myItemManager = new ItemManager();

items variable becomes hidden after the execution of ItemManager function, but addItem and removeItem still share the access to items. See the Douglas Crockford's article on private variables in JavaScript for further investigation.

aga
  • 27,954
  • 13
  • 86
  • 121
  • In addition to the comment above: this would create a new set of anonymous functions (assigned to `addItem` and `removeItem` properties) for every separated object. – zerkms Nov 01 '13 at 11:25
  • @Passerby yeah, I see it... I'll try to find out why. thanks for your comment. – aga Nov 01 '13 at 11:25
  • @aga: that's easy - because on every constructor call you're returning a new object – zerkms Nov 01 '13 at 11:25
  • @zerkms take a look at the following piece of code: `var a = []; a instanceOf Array;` Here I create a new object, but it's still instance of `Array`. Why does it work? – aga Nov 01 '13 at 11:28
  • That's basically the way I did it until today, but the problem with this pattern ist, that you cannot inherit it and as stated before it will always create a new object. But thank you! – GoldenerAal Nov 01 '13 at 11:29
  • 1
    @aga: because you're creating an instance of `Array` type object. Check http://stackoverflow.com/a/1978474/251311 for details – zerkms Nov 01 '13 at 11:29
1

There are several ways to have private variables:

I favor Symbols, though they can still be found using reflection (i.e. not completely private). Example:

var Person = (function() {
    var nameSymbol = Symbol('name');
​
    function Person(name) {
        this[nameSymbol] = name;
    }
​
    Person.prototype.getName = function() {
        return this[nameSymbol];
    };
​
    return Person;
}());

So it's possible to have (reasonably) private variables, but unfortunately none of the solutions are as elegant as you'd like.

Peter Tseng
  • 13,613
  • 4
  • 67
  • 57
-1

as GoldenerAal mentioned, they are not called classes, but functions you have

var ItemManager = function (){
..
...
...

};

you could have:

function ItemManager(){
this.items = [];

function addItem(item){
...
};
};

you can then create an instance of ItemManager, only when you need to :

var itemManager = new ItemManager();
itemManager.addItem(<something here>);

http://javascript.crockford.com/private.html variables inside a function only have the scope of that function, that variable is not a global variable (static variable).

tommy knocker
  • 371
  • 1
  • 7
  • 19