2

Let's say I have the following class:

function MyClass(){

    this.public = function(){
        console.log(private);
    };

    var private = 10;
}


var test = new MyClass;

test.public(); // logs 10
test.private; // undefined

I want to know if I can access the private variable from the outside. Looking at chrome's console it seems to be possible, since its context is shown:

enter image description here

EDIT: Just to clarify: I know how to properly expose it. Just want to be sure if there isn't some hacky way to access it.

GBarroso
  • 467
  • 1
  • 8
  • 19
  • `private` is not a property of `test` object to be accessed using `.` notation..Variable inside closure can only be accessed inside closure.. – Rayon May 29 '16 at 04:26
  • First, it's not a good idea to expose private member variables. Second, a function isn't a class. Please don't confuse Javascript with an object oriented language. Third, just create something like an IIFE and return something with a getter function for your private variable. Check out: https://en.wikipedia.org/wiki/Immediately-invoked_function_expression – Tad Donaghe May 29 '16 at 04:27
  • Yeah I know it isn't a real class. I'm not using this code I just want to know if it IS possible or not – GBarroso May 29 '16 at 04:28
  • 1
    I don't think there's any built in way of doing proper reflection in Javascript. There may be libraries that fake it. Chrome can do it just because the V8 engine probably has hacky stuff built in that would only work with V8. Google "Javascript reflection" – Tad Donaghe May 29 '16 at 04:33
  • You will have to expose it with a getter like: `this. getPrivate = function() {return private; } ` – Irshu May 29 '16 at 04:34
  • Possible duplicate of [How do JavaScript closures work?](http://stackoverflow.com/questions/111102/how-do-javascript-closures-work) –  May 29 '16 at 04:39

3 Answers3

6

Your private variable is local to that function scope and within Javascript, there is no access to variables inside a scope from outside the scope. You can ONLY access it from within the scope. There are no ways to get around this from Javascript code itself.

What a debugger can do (which has access to the VM internals) is different than what regular Javascript code can do. The debugger can look inside of scopes, but JS code from outside the scope cannot.

Obviously you can make an accessor for it, but without an accessor, there is no way to get to it from the outside.

jfriend00
  • 683,504
  • 96
  • 985
  • 979
2

The variable private is "trapped" inside MyClass's closure. You cannot access it unless some code exposes it, like a "getter" function.

function MyClass(){

    this.getter= function(){
        return private;
    };

    var private = 10;
}

By the way, private is a reserved keyword.

Joseph
  • 117,725
  • 30
  • 181
  • 234
0

There's one hacky, but not super-convenient, method.

Drop a breakpoint somewhere that has access to the scope.

function MyClass(){

    this.public = function(){
        console.log(private); // <<< BREAKPOINT HERE!
    };

    var private = 10;
}

Now call the function that is public that'll get you to that breakpoint.

While you're stuck there, pull private into global scope however you'd like by typing something like this on the console:

var window.foo = private;

Profit. You can now grab foo from the console whenever you'd like.

And you can do this for anything available in scope there. If you had var private2 = 7; in there under var private, you've got access to it, too, even if it's not used in this.public.


Pros:

  • Access the value any time while you're debugging.
  • Congrats! You're peak hipster.

Cons:

  • Reload the page and you've gotta hack it again.
  • If you forget and put two foos into global state, you'll overwrite the second.

I keep figuring there's gotta be a sneakier (and more convenient) way, maybe like monkeypatching a public method back into itself with eval with the scope breaking code like the above (which would eliminate the breakpoint calling), but haven't quite found it yet.

ruffin
  • 16,507
  • 9
  • 88
  • 138