为什么onevent属性被视为内存快照中的闭包?

huangapple go评论101阅读模式
英文:

Why the onevent properties are being treated as closure in memory snapshot?

问题

当我在触发largeClosures()stopAndClear()点击事件处理程序之后,拍摄内存快照,我可以看到(closure)行包含这些事件处理程序。

这些事件处理程序通过使用onevent属性绑定到DOM元素。

例如:

<!-- begin snippet: js hide: false console: true babel: false -->

<!-- language: lang-html -->
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>

<body>
  <p>Analyze the impact of closures on memory</p>
  <p>
    <button onclick="largeClosures()">
      Closures maintain hold on large string
    </button>
  </p>
  <p>
    <button onclick="smallClosures()">
      Closures maintain hold only on small strings
    </button>
  </p>
  <p>
    <button onclick="evalClosures()">Closures with <code>eval</code></button>
  </p>
  <button onclick="stopAndClear()">Stop and clear</button>
  <script>
    var closures = [];

    function createLargeClosure() {
      var largeStr = new Array(1000000).join("x");
      return function lC() {
        return largeStr;
      };
    }

    function createSmallClosure() {
      var smallStr = "x";
      var largeStr = new Array(1000000).join("x");
      return function sC() {
        return smallStr;
      };
    }

    function createEvalClosure() {
      var smallStr = "x";
      var largeStr = new Array(1000000).join("x");
      return function eC() {
        eval("");
        return smallStr;
      };
    }

    function largeClosures() {
      closures.push(createLargeClosure());
    }

    function smallClosures() {
      closures.push(createSmallClosure());
    }

    function evalClosures() {
      closures.push(createEvalClosure());
    }

    function clear() {
      closures.length = 0;
    }

    function stopAndClear() {
      clear();
    }
  </script>
</body>

</html>

<!-- end snippet -->

内存快照(使用Microsoft Edge Developer Tool - Memory):

为什么onevent属性被视为内存快照中的闭包?

正如你所见,(closure)包含这两个点击事件处理程序。它们每个都分配了32字节的内存。为什么它们被视为闭包?传统的闭包应该像lCsCeC函数一样。

英文:

When I take a memory snapshot after triggering the largeClosures() and stopAndClear() click event handler. I can see the (closure) row contains these event handlers.

These event handlers are bound to the DOM element by Using onevent properties.

For example:

<!-- begin snippet: js hide: false console: true babel: false -->

<!-- language: lang-html -->

&lt;!DOCTYPE html&gt;
&lt;html lang=&quot;en&quot;&gt;
&lt;head&gt;
&lt;meta charset=&quot;UTF-8&quot;&gt;
&lt;meta name=&quot;viewport&quot; content=&quot;width=device-width, initial-scale=1.0&quot;&gt;
&lt;title&gt;Document&lt;/title&gt;
&lt;/head&gt;
&lt;body&gt;
&lt;p&gt;Analyze the impact of closures on memory&lt;/p&gt;
&lt;p&gt;
&lt;button onclick=&quot;largeClosures()&quot;&gt;
Closures maintain hold on large string
&lt;/button&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;button onclick=&quot;smallClosures()&quot;&gt;
Closures maintain hold only on small strings
&lt;/button&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;button onclick=&quot;evalClosures()&quot;&gt;Closures with &lt;code&gt;eval&lt;/code&gt;&lt;/button&gt;
&lt;/p&gt;
&lt;button onclick=&quot;stopAndClear()&quot;&gt;Stop and clear&lt;/button&gt;
&lt;script&gt;
var closures = [];
function createLargeClosure() {
var largeStr = new Array(1000000).join(&quot;x&quot;);
return function lC() {
return largeStr;
};
}
function createSmallClosure() {
var smallStr = &quot;x&quot;;
var largeStr = new Array(1000000).join(&quot;x&quot;);
return function sC() {
return smallStr;
};
}
function createEvalClosure() {
var smallStr = &quot;x&quot;;
var largeStr = new Array(1000000).join(&quot;x&quot;);
return function eC() {
eval(&quot;&quot;);
return smallStr;
};
}
function largeClosures() {
closures.push(createLargeClosure());
}
function smallClosures() {
closures.push(createSmallClosure());
}
function evalClosures() {
closures.push(createEvalClosure());
}
function clear() {
closures.length = 0;
}
function stopAndClear() {
clear();
}
&lt;/script&gt;
&lt;/body&gt;
&lt;/html&gt;

<!-- end snippet -->

Memory snapshot(using Microsoft Edge Developer Tool - Memory):

为什么onevent属性被视为内存快照中的闭包?

As you can see, the (closure) contains these two click event handlers. Each of them has 32 bytes of memory allocated. Why they are being treated as a closure? The traditional closure should be like lC, sC, and eC functions.

答案1

得分: 0

事件处理程序 捕获它们创建时的周围上下文,形成一个 闭包 来保持对在定义它们时处于范围内的变量和函数的访问。

在您的 HTML 代码 中,当您为按钮定义一个 onclick 属性,比如 button onclick="largeClosures()",实际上是创建了一个包含整个函数定义所在范围的函数(闭包),其中包括闭包数组和在 :?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定