Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it possible to access private variables in a module pattern dynamically?

Is there a way to have a public function from the module-pattern accessing private variables dynamically? test1 shows what I mean with "access dynamically" but with public variables

var x = (function(){
    var x=0, y=2, z=5;

    return {
        toast: 123,
        test1: function(arg){
            return this[arg];
        },
        test2: function(){
            // ??
        }
    };
}());

console.log(x.test1("toast")); // 123
console.log(x.test2("y")); // should return 2

I ended up with creating a single private variable (an object) storing my private variables so I was able to access them like that

 privateVarStore[privateVarName]

But is there another solution for that?

like image 727
Tim Friedrich Avatar asked Dec 25 '11 04:12

Tim Friedrich


People also ask

Are private variables visible to subclasses?

The answer is No. They do not. OBJECTS of subclasses contain private fields of their superclasses.

Can private variables be accessed?

Private variables can be accessed only inside the class that it belongs to, but it cannot be accessed by outside class.


2 Answers

DEMO

Yes.

Sorry to disappoint Adam Rackis but you can do it with (the evil) eval:

var x = (function(){
    var x=0, y=2, z=5;

    return {
        toast: 123,
        test1: function(arg){
            return this[arg];
        },
        test2: function(a){
            return eval(a)
        }
    };
}());

console.log(x.test1("toast")); // 123
console.log(x.test2("y")); // should return 2  -> does return 2

This is one of those few exceptions where eval should be used.

EDIT, as per Hans B PUFAL suggestion (comment), you can and should validate the parameter in test2 as follows:

test2: function(a){
    return /^[$_a-z][$_a-z0-9]*$/i.test (a) ? eval(a) : undefined;
}
like image 135
qwertymk Avatar answered Sep 21 '22 05:09

qwertymk


No (at least not without resorting to eval, per qwertymk's answer).

y is not a property of x (consider naming this object something better than x to avoid confusion with the local variable x). y is a local variable over which x's methods have formed a closure.

Any of x's methods may access y, but not by saying this.y, but rather by accessing y directly.

Again, y is not a property of your object x. It's just a local variable in the function that created x, thereby causing x's methods to form a closure over it.

So, to get test2 to return y, just do:

test2: function(){
    return y;
}

To create a method allowing you to access private variables, consider something like this:

var x = (function () {
    var privateMembers = { x: 0, y: 2, z: 5 };

    return {
        getPrivate: function (name) {
            return privateMembers[name];
        },
        toast: 123,
        test1: function (arg) {
             return this[arg];
        },
        test2: function () {
           // ??
        }
    };
})();

And then

alert(x.getPrivate("y")); //alerts 2

Check out this fiddle

like image 33
Adam Rackis Avatar answered Sep 20 '22 05:09

Adam Rackis