Question

I have this code here:

var Person = (function() {
    var name;

    var PersonConstructor = function(n) {
        name = n;
    };

    PersonConstructor.prototype.getName = function() {
        return name;
    };

    return PersonConstructor;

})();

var people = [];
var person1 = new Person("Foo");
var person2 = new Person("Bar");
alert(person1.getName()); // I want it to be Foo
people.push(person1);
people.push(person2);

I got the idea of emulating classes from here.. But of course, I neglected the fact that the private variable var name; is also a static variable. Since this is tripping my current efforts I would like to know if there is a way to keep the private behaviour in this example but avoid the static one?

Was it helpful?

Solution

There is no "private" when working with prototypes.

It should be noted there is no value in private state, avoid it like the plague. Closures are ugly and expensive.

var o = {
    name: value
}

However if you insist on being delusional and want private state badly then

You can store state in a closure

function nameHolder(name) {
    return {
        get name() {
            return name
        },
        set name(n) {
            name = n
        }
    }
}

Note this is highly inefficient and has little benefit.

Alternatively you can store state in a weakmap

function privates() {
    var map = new WeakMap()

    return function (key) {
        var v = map.get(key)
        if (!v) {
            v = {}
            map.set(key, v)
        }
        return v
    }
}

var NameHolder = (function () {
    var state = privates()

    return {
        constructor: function (name) {
            state(this).name = name
        },
        getName: function () {
            return state(this).name
        }
    }
}())

WeakMap browser support is non-existant so emulate it using pd.Name

OTHER TIPS

Use this.

var Person = (function() {
  var PersonConstructor = function(n) {
    this.name = n;
  };

  PersonConstructor.prototype.getName = function() {
    return this.name;
  };

  return PersonConstructor;    
})();

Unfortunately, this won't preserve the private state.

It's just a scope issue.

var Person = (function(){

    var PersonConstructor = function(n){ 
        // *************************************************************** 
        // PRIVATE VARIABLES AND FUNCTIONS 
        // ONLY PRIVELEGED METHODS MAY VIEW/EDIT/INVOKE 
        // *************************************************************** 

        var myName=n?n:"John Doe";

        // *************************************************************** 
        // PRIVILEGED METHODS 
        // MAY BE INVOKED PUBLICLY AND MAY ACCESS PRIVATE ITEMS 
        // MAY NOT BE CHANGED; MAY BE REPLACED WITH PUBLIC FLAVORS 
        // *************************************************************** 
        this.toString=this.getName=function(){ return myName } 
    } 
    return PersonConstructor;
})();

var person1 = new Person("foo");
var person2 = new Person("bar");

alert(person1.getName());
alert(person1.toString());
alert(person1.myName);

// alerts "foo", "foo", undefined

EDIT - Here is my original solution.

var Person = function(n){ 
    // *************************************************************** 
    // PRIVATE VARIABLES AND FUNCTIONS 
    // ONLY PRIVELEGED METHODS MAY VIEW/EDIT/INVOKE 
    // *************************************************************** 

    var myName=n?n:"John Doe";

    // *************************************************************** 
    // PRIVILEGED METHODS 
    // MAY BE INVOKED PUBLICLY AND MAY ACCESS PRIVATE ITEMS 
    // MAY NOT BE CHANGED; MAY BE REPLACED WITH PUBLIC FLAVORS 
    // *************************************************************** 
    this.toString=this.getName=function(){ return myName } 

} 

var person1 = new Person("foo");
var person2 = new Person("bar");

alert(person1.getName());
alert(person1.toString());
alert(person1.myName);

// alerts "foo", "foo", undefined
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top