【问题标题】:Is using var foo = function foo() {}; expression creating a memory leak in IE < 9?正在使用 var foo = function foo() {};在 IE < 9 中创建内存泄漏的表达式?
【发布时间】:2013-05-30 11:09:08
【问题描述】:

我知道这个表格:

var foo = function bar() {};

会将bar 名称泄漏到封闭范围,并在jscript 中创建两个函数。

怎么样:

var foo = function foo() {};

?

它仍然将名称泄漏到封闭范围,但无论如何它都在那里(感谢var foo)。

我知道它将在整个范围内定义,但它会创建两个函数并立即取消引用/销毁其中一个,还是这仍然会导致泄漏?

在这种情况下:

var bar = function() {
    foo();
    var foo = function foo() {};
}

bar() 内部会不会有两个函数对象?

编辑

好吧,它肯定会创建两个函数对象,现在的问题是:由命名定义创建的函数是否在 var foo 行之后被 GC 取消引用和清理,所以不超过一个“活”@987654330 @instance 在上面的代码中的任何时候?

或者 IE 是 IE 会让它永远悬而未决,因为没有办法“取消引用”由定义创建的 foo,它甚至不应该放在首位?

【问题讨论】:

  • "in IE"...仅供参考,自 IE9 以来已修复...
  • @Christoph 改变了问题,谢谢
  • @user1737909 那篇文章没有具体说明函数和变量名称相同的var foo = function foo() {};。特别是,文章提到手动取消引用名称。我想知道在我的情况下是否一切都得到了很好的清理。
  • 理论上,这将创建一个被提升的函数声明,然后一旦到达代码中的该行,就会用函数表达式覆盖函数定义,从而允许对原始函数进行垃圾收集。奇怪的是,如果这样做了,当在函数上调用 toString() 时,它会显示函数的名称,即使函数名称范围的奇怪泄漏也是如此。

标签: javascript internet-explorer jscript


【解决方案1】:

在解析语句var foo = function foo() {}; 时,var foo 声明很可能在 function foo(){} 执行后被赋值。

这意味着function foo 将首先在全局范围内定义,通常是window

之后,var foo 被分配,因此将 window.foo 从名称 foo 的范围中隐藏起来。所以实际上,您的代码定义了window.foowindow.bar,如果您的当前范围离开,则不会被垃圾回收。

【讨论】:

  • 为什么要在全局范围内定义函数?
  • 因为function foo(){} 的行为类似于foo=function(){}。并且foo=something; 没有var 语句实际上会在全局范围为window 时断言window.foo,这是浏览器脚本的默认值。
  • 这意味着每个函数声明都是全局的,这是不正确的。 function foo() {}等同于foo=function(){}
  • 命名函数表达式对于 a) 调试和 b) 递归很有用。规范定义了这样一个函数的名称应该只在函数本身内部可见,即在封闭范围内不泄漏。但它是 IE (
  • 我不认为 Chrome 的 JavaScript 引擎对待这些不同。规范中定义该名称仅在函数内部可见,且已知只有IE存在此问题。
猜你喜欢
  • 1970-01-01
  • 2015-05-06
  • 2011-05-17
  • 1970-01-01
  • 2013-03-03
  • 2011-03-24
  • 2023-03-17
  • 2023-04-06
  • 1970-01-01
相关资源
最近更新 更多