sbr
sbr

Reputation: 4823

how to have Javascript Object creation pattern with Reusable methods and private properties?

Considering object creation patterns with private properties, one way to do is :

function MyStack (){
    var list = [],
        index = 0;

    this.push =  function(val){ 
        return list[index++] = val;
    };
    this.pop = function(){// ...}
}

var stack1 = new MyStack();       stack1.push(5);
var stack2 = new MyStack();       stack2.push(11);

Problem with this: Every instance of Stack has it's own copy of methods 'push' and 'pop'.

Another way for implementing constructor method is:

function MyStack(){ 
    this.list = []; 
    this.index = 0;
}
MyStack.prototype = {
    insert: function(val){
            return this.list[this.index++] = val;
        },
    pop:function(){//...}
}

Problem here: We lose the privacy of list and index.

Is there a way, such that we can have both methods reuse among instances and privacy of properties ?

I understand that we can have this for methods that don't operate on any state of the object, but I am talking more about those methods that do operate on the state.

Upvotes: 11

Views: 474

Answers (4)

netpoetica
netpoetica

Reputation: 3425

Yes. I've edited this code so it's actually fully functional as you had intended it to work. It seems a bit redundant to me, but, it does provide you the ability to provide a public interface, but to keep your variables private and control the way the user interacts with them.

function MyStack(){ 
    var list = []; 
    var index = 0;

    this.getIndex = function(){
        return index;
    }
    this.setIndex = function(val){
        index = val;
    }
    this.list = function(val){
        if(val){
           // setter if a value was provided. Illustrating how you can control
           // index, which I assume is the point of having these things private 
           // to begin with
           return list[this.setIndex(this.getIndex() + 1)] = val;
        }

        // always return list - acts like a getter
        return list;
    }
}
MyStack.prototype = {
    insert: function(val){
            return this.list(val);
        },
    pop:function(){}
}

var stack1 = new MyStack();       
stack1.insert(5);
var stack2 = new MyStack();       
stack2.insert(11);

Upvotes: 1

slobo
slobo

Reputation: 761

A constructor function may return any object (not necesserily this). One could create a constructor function, that returns a proxy object, that contains proxy methods to the "real" methods of the "real" instance object. This may sound complicated, but it is not; here is a code snippet:

var MyClass = function() {
    var instanceObj = this;
    var proxyObj = {
        myPublicMethod: function() {
            return instanceObj.myPublicMethod.apply(instanceObj, arguments);
        }
    }
    return proxyObj;
};
MyClass.prototype = {
    _myPrivateMethod: function() {
        ...
    },
    myPublicMethod: function() {
        ...
    }
};

The nice thing is that the proxy creation can be automated, if we define a convention for naming the protected methods. I created a little library that does exactly this: http://idya.github.com/oolib/

Upvotes: 1

Ryan Wheale
Ryan Wheale

Reputation: 28390

You should check out John Resig's Simple Javascript Inheritance. It is a great read, and it has been extended to provide support for privates, aptly called Privates.js;

Upvotes: 1

Engineer
Engineer

Reputation: 227

I think in both approaches you mentioned, When ever object is created using constructor pattern the properties will get copied to its objects. This you mentioned for the 1st approach as the concern. I feel the same will be applied for the second approach also along with your concern in this approach.

We generally go to the second approach you mentioned when ever we want to extend the properties of "MyStack" to some other class.

Lets say i want to extend your class MyStack to MyTest like below

var dummy = function();
dummy.prototype = MyStack.prototype;
var MyTest = function(){
};
MyTest.prototype = new dummy(); // Assigning MyStack properties to MyTest
var obj = new MyTest();

Upvotes: 0

Related Questions