Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there anyway to have instances share the same function yet at the same time have private variables?

I have this piece of code:

var Human=function(name){
  this._name=name;
};
Human.prototype.Shout=function(){
  alert(this._name);
};

var tom=new Human("tom");
var john=new Human("john");
alert(tom.Shout===john.Shout);

Right now ._name is not "private". I want to make ._name "private", but at the same time i do not wish to create additional functions for each instance of Human (in other words tom.Shout Must be === to john.Shout) because creating additional functions for each instance is just well.. unnecessary (ok offtopic - we can debate this on another thread)

My conclusion is that what I'm trying to achieve (having ._name be "private" and at the same time having tom.Shout===john.Shout) is impossible.

But I just want to be 200% sure before jumping into any conclusions.

(I welcome any hacks as long as the requirements are met, i.e no creating of additional functions for each instance)

If we have to create additional functions to do scoping that's fine but that number should be a fixed number and that number should not increase with each additional instance of Human.

like image 313
Pacerier Avatar asked May 13 '11 22:05

Pacerier


People also ask

Can methods in the same class access private variables?

That means you can access private members as long as you are accessing them in the same class as they are declared. You can even access private non-static members from a static context in the same class using an instance. There is no access modifier that only allows access from the same instance.

Can two objects from the same class access each other's private variables?

This is perfectly legal. Objects of the same type have access to one another's private variables. This is because access restrictions apply at the class or type level (all instances of a class) rather than at the object level (this particular instance of a class).

How do you access private variables in another class?

By using Public Method We can access a private variable in a different class by putting that variable with in a Public method and calling that method from another class by creating object of that class.


1 Answers

Update

Your looking for @name which is an instance variable. Pray it's in es.next, but we don't have it yet. Maybe in two years.

If you care about a clean API then here is your solution:

function Class(foo) {
    Class.priv(this).foo = foo;
}

Class.priv = (function() {
    var cache = [],
        uid = 1;

    return function(obj) {
        if (!this.__id) {
            this.__id = uid;
            cache[uid++] = {};
        }
        return cache[this.__id];
    };

}());

Class.prototype.bar = function() {
    console.log(Class.priv(this).foo);
}

Store all the data in a cache as a function of the constructor. No data is cluttered on the object.

Original

However there is no such thing as "private".

All you can do is create a local variable inside a function.

The constructor function

var Human = function(name) {
    // local variable.
    var _name = name;
}

Has a local variable that by very definition of being local is not usable outside of the constructor function.

This means that you cannot access it in external code like the prototype.

What you can do however is make it read only using ES5

var Human = function(name) {
    Object.defineProperty(this, "name", { value: name });
}

If you can truly achieve what your asking, you'd make a huge breakthrough in js. I've attempted to do just that for many hours.

A different pattern would be :

var Human = function(name) {
   this.name = name;

   return {
       Shout: this.Shout.bind(this)
   };
}

Human.prototype.Shout = function() {
   console.log(this.name);
}

This has the overhead of calling .bind and creating a new object for every instance though.

like image 69
Raynos Avatar answered Oct 28 '22 07:10

Raynos