Ming
Ming

Reputation: 1693

Access a var defined inside a closure from outside (i.e. the scope where the closure was defined)

For background, I am currently playing through Untrusted, a JavaScript-based programming game whose core mechanic is editing code to modify the game world to progress forward. I have solved most levels the "intended" way by modifying the variables I am given in the local scope using the documented in-game API. However, I am wondering if there are also some "unintended" ways to modify the game state/game definition by fishing around.

A lot of the game has code as follows (evaluated in window scope):

function foo() {
    var bar = 1234;
}

I understand that I can access foo from any scope by referring to window.foo. Is there a way I can access bar inside foo even though it is not explicitly exposed?

To clarify, the above code is already evaluated for me (in window scope, I believe, so I can at least get a reference to the foo). I can not change what is evaluated. (I suppose I could redefine foo if I really wanted, and that would bypass a lot of restrictions, but that's tangential to the current direction of questioning.) Rather, my goal is, given this has already been evaluated, modify it in place (such as setting a new value for bar).

Thanks in advance!

Upvotes: 1

Views: 92

Answers (2)

Inkbug
Inkbug

Reputation: 1692

Without modifying foo, you cannot access bar from outside foo.

However, it is not hard to modify foo:

//Original code
function foo ( ) {
  var bar = 1234;
}

//Modify foo:
(function(){
  var fooMatches = foo.toString().replace(/var\s+bar/g, "window.bar").match(/^\s*function\s+foo\s*\(([^()]*)\)\s*{([^\0]*)}\s*$/);
  var args = fooMatches[1].split(/\s*,\s*/);
  args.push( fooMatches[2] );
  foo = Function.apply( window, args );
})();

//Access bar
foo();
alert( bar );

Upvotes: 0

slebetman
slebetman

Reputation: 113906

The short answer is no.

It's not possible to access a local variable outside of it's scopes/closures (note that due to closures, there may be more than one scope that can access a single local variable).


For the long answer, see this answer for a description of how scopes work: javascript can't access private properties.

Upvotes: 4

Related Questions