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

时间:2012-06-25 15:59:28

标签: javascript scope closures

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

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

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

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

//access y here with x somehow

4 个答案:

答案 0 :(得分:4)

这是(关闭)目的之一 - 保持信息私密性。由于函数已经被执行,它的范围变量不再可以从外部获得(并且从未有过) - 只有在其范围内执行的函数(仍然)才能访问。

但是你可以通过getter / setter提供访问权限。

您可能需要了解有关闭包的Stuart Langridge's talk。非常值得推荐的还有Douglas Crockfords Explanations。你可以用闭包做很多花哨的东西;)

编辑: 您有几个选项来检查闭包:在webdeveloper控制台中观察对象或(我经常这样做)返回一个调试函数,它将所有私有变量转储到控制台。

答案 1 :(得分:3)

不,除非你揭露它:

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

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


    x.setY(4);

答案 2 :(得分:2)

您可以编辑提醒功能:

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

或者,如果您拥有代码,则可以使用标准的getter和setter。

答案 3 :(得分:0)

如果可以在 prior 脚本标签中执行自己的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>

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

如果其他脚本使用的是src而不是内联代码,则将变得更加困难-您必须获取script标签的文本(可能将请求从另一台服务器上退回以避免CORS问题),然后才能进行所需的替换并插入修补的代码。 (或者,如果您有服务器,则可以让 server 进行文本替换-然后,您所需要做的就是更改插入的脚本标签的src指向您的服务器而不是默认位置。)