Over a million developers have joined DZone.
{{announcement.body}}
{{announcement.title}}

Prototypes and Private State

DZone's Guide to

Prototypes and Private State

· Web Dev Zone
Free Resource

Add user login and MFA to your next project in minutes. Create a free Okta developer account, drop in one of our SDKs to your application and get back to building.

 

"private" state in JavaScript means using local state in a constructor function and returning methods which are in scope of that local data. This pattern is not compatible with prototypes.

The following is reposted from Jake Verbaten's blog, Raynos

 

An example:

Live Example

function Parent() {
    // a is private
    var a = 42;

    this.printA() {
        console.log(a);    
    }
}

Parent.prototype.doubleA = function() {
    // How do I access a?
}

There is simply no way you can use "private" state and prototypes because here "private" means local variables inside a constructor.

This is simply the wrong way to do private state. A better solution for private state is a Name. The following examples will use pd to give us an implementation of a Name A Name is a function, given any key will return an object attached to that key.

You can only get that object if you have both the Name and the key. Let's look at an example:

Live Example

var Parent = (function () {
    // "private" Name
    var privates = pd.Name();

    Parent.prototype.doubleA = function() {
        // _ is the unique object
        var _ = privates(this);
        _.a = _.a * 2;
    };

    Parent.prototype.printA = function () {
        // print from the unique object for this instance
        console.log(privates(this).a);    
    };

    return Parent;

    function Parent() {
        // set a on the unique object for this instance
        privates(this).a = 42;
    }
})();

var p = new Parent;
p.doubleA();
p.printA();

Now we can give this a bit of sugar and have an inheritance mechanism using these private Names. Using a function like klass

Live Example:

var Parent = klass(function (privates) {
    // this becomes Parent.prototype
    // Parent becomes the constructor function
    return {
        constructor: function () {
            privates(this).a = 42; 
        },
        printA: function () {
            console.log(privates(this).a);
        }
    };
});

var Child = klass(Parent, function (privates, $super) {
    // the privates Name object is the same as the one used in Parent
    // This becomes Child.prototype. 
    // Child.prototype will inherit from Parent.prototype
    // Child becomes the constructor
    return {
        constructor: function () {
            // $super === Parent.prototype
            $super.constructor.call(this);   
        },
        doubleA: function () {
            var _ = privates(this);
            _.a = _.a * 2;   
        }
    };  
});

var c = new Child;
c.doubleA();
c.printA();

Note that using privates(this).a over this._a has a run-time overhead and a memory overhead.

One needs to choose between "do I want efficient code" or "do I want real hidden state".

 

 

Launch your application faster with Okta’s user management API. Register today for the free forever developer edition!

Topics:

Opinions expressed by DZone contributors are their own.

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}