是否可以访问函数的闭包?

Den*_*ret 9 javascript closures scope

javascript中的函数通过保持(隐藏)链接到其封闭范围来形成闭包.

当我们有函数(作为变量值)时,是否可以以编程方式访问它?

真正的目标是理论上的,但演示可能是列出闭包的属性.

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

//access y here with x somehow
Run Code Online (Sandbox Code Playgroud)

Cer*_*nce 5

如果您处于前端环境中,并且可以在先前的脚本标记中执行自己的Javascript,则可以选择附加 MutationObserver,等待您要监视的脚本标记插入到文档中,当它插入时,更改其代码,以便公开您想要检查或更改的功能。这是一个例子:

<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>
Run Code Online (Sandbox Code Playgroud)

这可能不是您想要的,但这种方法是侵入闭包的极少数方法之一,当页面运行您无法更改的代码时,这是一种有用的技术。

如果其他脚本有一个src而不是内联代码,那就有点困难了。当<script>MutationObserver 看到该标签时,对其进行调整或将其替换为新的脚本标签,该脚本标签textContent是原始脚本内容加上您的修改。为了获取原始内容,要么检查内置内容<script>并对其替换进行硬编码,要么获取脚本标记的文本(可能从另一台服务器退回请求以避免 CORS 问题),然后才能进行所需的替换和插入修补后的代码。(或者,如果您有服务器,则可以让服务器执行文本替换 - 然后,您所需要做的就是更改src插入的脚本标记以指向您的服务器而不是默认位置。)


Chr*_*oph 4

这就是闭包的目的之一——保持信息的私密性。由于函数已经被执行,它的作用域变量不再从外部可用(并且从来没有) - 只有在其作用域中执行的函数(仍然)可以访问。

但是您可以通过 getter/setter 授予访问权限。

您可能想看看Stuart Langridge关于闭包的讨论。道格拉斯·克罗克福德 (Douglas Crockfords) 的解释也非常值得推荐。你可以用闭包做很多奇特的事情;)

编辑:您有多种选择来检查闭包:在 Webdeveloper 控制台中观察对象或(就像我经常做的那样)返回一个调试函数,该函数将所有私有变量转储到控制台。