简体   繁体   中英

Accessing “private” variables in javascript

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:

在此处输入图片说明

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.

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.

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 .

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 foo s 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.

I have tried adding a getter function from outside but seemed not to work.

something like this. If anyone has any idea about how to do this-like i would be really glad to read it.

test('testing MyClass private var', () = {
  const priv = new MyClass()
  priv.getPrivate = function(){return this.private}
  
 expect(priv.getPrivate()).toBe(10)

})

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM