Is it possible to gain access to the closure of a function?

If you're in a front-end environment, and if you can execute your own Javascript in a prior script tag, an option is to attach a MutationObserver, wait for the script tag you want to spy on to be inserted into the document, and right when it's inserted, change its code so that the functionality you want to examine or change gets exposed. Here's an example:

<script>
new MutationObserver((mutations, observer) => {
  // Find whether the script tag you want to tamper with exists
  // If you can't predictably identify its location,
  // you may have to iterate through the mutations' addedNodes
  const tamperTarget = document.querySelector('script + script');
  if (!tamperTarget) {
    return;
  }
  observer.disconnect();
  console.log('Target script getting tampered with');
  tamperTarget.textContent = tamperTarget.textContent.replace(
    'return function',
    'window.y = y; return function'
  );
  setTimeout(() => {
    console.log("Hacked into tamper target's script and found a y of", y);
    console.log('Could also have replaced the local y with another value');
  });
})
  .observe(document.body, { childList: true });

</script>

<script>
console.log('Tamper target script running');
var x = (function(){
   var y = 5;
   return function() {
       alert(y);
   };
})();
</script>

This may not have been what you had in mind, but this sort of method is one of the very few ways to hack into a closure, which is a useful technique when the page runs code you can't change.

If the other script has a src instead of inline code, it'll be a bit harder. When the <script> tag is seen by the MutationObserver, tweak it or replace it with a new script tag whose textContent is the original script contents plus your modifications. In order to get the original contents, either examine the built-in <script> and hard-code its replacement, or fetch the text of the script tag (possibly bouncing the request off another server to avoid CORS issues) before you can make the required replacements and insert the patched code. (Or, if you have a server, you could have the server do the text replacements - then, all you need to do is change the src of the inserted script tag to point to your server rather than the default location.)


That's (one of) the purpose(s) of a closure - to keep information private. Since the function already has been executed its scope variables are no longer available from outside (and have never been) - only the functions executed in it's scope (still) have access.

However you could give access via getters/setters.

You might want to take a look into Stuart Langridge's talk about closures. Very recommendable are also Douglas Crockfords Explanations. You can do lots of fancy stuff with closures;)

Edit: You have several options to examine the closure: Watch the object in the webdeveloper console or (as I do it often) return a debug-function which dumps out all the private variables to the console.


You can edit the alert function:

var x = (function(){
   var y = 5;
   return function() {
       alert(y);
   };
})();

var oldAlert = alert;

alert = function (x) {
    oldAlert(x);
    window.y = x;
}

x();

console.log(y); // 5

Or if you own the code, you can use standart getters and setters.


No, not unless you expose it:

var x = function(){
        var y = 5;

        return {             
           getY: function(){
              return y;
          },
          setY: function(newY){
             y = newY;
          }    
       }
   }


    x.setY(4);