是什么导致错误“无法从释放的脚本中执行代码”

IT技术 javascript internet-explorer
2021-01-19 08:39:10

我以为我不久前找到了解决方案(请参阅我的博客):

如果您遇到 JavaScript(或者应该是 JScript)错误“无法从释放的脚本执行代码” - 尝试移动头部中的任何元标记,使它们位于您的脚本标记之前。

...但根据最近的一篇博客评论,我建议的修复方法可能并不适用于所有人。我认为这是向 StackOverflow 社区开放的好方法....

是什么导致错误“无法从释放的脚本执行代码”以及解决方案/变通方法是什么?

6个回答

当您调用在不再存在的窗口或框架中创建的函数时,您会收到此错误。

如果您事先不知道窗口是否仍然存在,您可以执行 try/catch 来检测它:

try
{
  f();
}
catch(e)
{
  if (e.number == -2146823277)
    // f is no longer available
    ...
}
我在移动到 $rootScope 的数组上使用 AngularJS 遇到了这个问题,所以我知道我可以访问该数组。但是,我无法再访问最初设置我的值的数组。使用angular.copy为我在我的变量中提供了一个新的数组实例,而不是一个指向我无法访问的旧变量的指针。
2021-03-25 08:39:10
我不确定,但我不会指望它。我猜 typeof f 会抛出错误,否则返回“函数”或“未知”。
2021-04-01 08:39:10
谢谢 Sjoerd ..但是为什么这会发生在 IE 中?
2021-04-01 08:39:10
这会做同样的事情吗?(typeof f == "undefined") { /* 无效 */ }
2021-04-03 08:39:10
我会使用0x800a1393而不是十进制整数-2146823277,因为谷歌搜索十六进制值会返回更多结果。另外,是否可以检查f给定示例中的函数以找出其用于日志记录的声明上下文?
2021-04-13 08:39:10

当脚本的“父”窗口被释放(即:关闭)但对仍然保留的脚本的引用(例如在另一个窗口中)被调用时,会导致错误。即使“对象”还活着,但它想要执行的上下文不是。

它有点脏,但它适用于我的 Windows 边栏小工具:

这是一般的想法:“主”窗口设置一个函数来评估一些代码,是的,它就是丑陋的。然后“子”可以调用这个“构建器函数”(它/绑定到主窗口的范围/)并取回一个也绑定到“主”窗口的函数。当然,一个明显的缺点是,被“反弹”的函数不能在它看似定义的范围内关闭......无论如何,足够的胡言乱语:

这是部分伪代码,但我在 Windows 侧边栏小工具上使用了它的一个变体(我一直这么说是因为侧边栏小工具在“不受限制的区域 0”中运行,这可能会——也可能不会——极大地改变场景。)


// This has to be setup from the main window, not a child/etc!
mainWindow.functionBuilder = function (func, args) {
  // trim the name, if any
  var funcStr = ("" + func).replace(/^function\s+[^\s(]+\s*\(/, "function (")
  try {
    var rebuilt
    eval("rebuilt = (" + funcStr + ")")
    return rebuilt(args)
  } catch (e) {
    alert("oops! " + e.message)
  }
}

// then in the child, as an example
// as stated above, even though function (args) looks like it's 
// a closure in the child scope, IT IS NOT. There you go :)
var x = {blerg: 2}
functionInMainWindowContenxt = mainWindow.functionBuilder(function (args) {
  // in here args is in the bound scope -- have at the child objects! :-/
  function fn (blah) {
    return blah * args.blerg
  }
  return fn
}, x)

x.blerg = 7
functionInMainWindowContext(6) // -> 42 if I did my math right

作为一个变体,主窗口应该能够将 functionBuilder 函数传递给子窗口——只要 functionBuilder 函数是在主窗口上下文中定义的!

我觉得我用了太多的词。天啊。

我刚刚收到错误。我正在做类似于上面的代码 - iframe 在父窗口的范围内调用 js。哈哈哈好玩:)
2021-03-28 08:39:10
因为我刚刚花了大约 2 天的时间...让我注意,您可以在 IE 中使用 SignalR 的永久帧传输机制遇到此类错误。消息(对象)在 iFrame 中接收/创建,然后传递给主应用程序。创建这些对象的 iFrame 稍后可能会被处理,你会得到随机错误......例如,调用obj.hasOwnProperty()来自先前 SignalR 消息的对象。
2021-04-12 08:39:10

这是一个非常具体的案例,我在其中看到了这种行为。它在 IE6 和 IE7 中对我来说是可重现的。

从 iframe 中:

window.parent.mySpecialHandler = function() { ...work... }

然后,在使用新内容重新加载 iframe 后,在包含 iframe 的窗口中:

window.mySpecialHandler();

此调用因“无法从释放的脚本执行代码”而失败,因为 mySpecialHandler 是在不再存在的上下文(iframe 的原始 DOM)中定义的。(重新加载 iframe 破坏了这个上下文。)

但是,您可以在父窗口中安全地设置“可序列化”值(原语、不直接引用函数的对象图)。如果你真的需要一个单独的窗口(在我的例子中是一个 iframe)来向远程窗口指定一些工作,你可以将工作作为字符串传递并在接收器中“评估”它。小心这一点,它通常不会带来干净或安全的实现。

如果您尝试访问 JS 对象,最简单的方法是创建一个副本:

var objectCopy = JSON.parse(JSON.stringify(object));

希望它会有所帮助。

请注意,如果对象包含以函数为值的属性,则不会使用此方法复制它们。
2021-04-12 08:39:10

当子窗口尝试与不再打开的父窗口通信时,MSIE 中可能会发生此错误。

(不完全是世界上最有用的错误消息文本。)

反之亦然(父母对孩子)
2021-03-17 08:39:10
当子窗口调用父窗口上的函数并向其传递一个参数然后关闭自身时,我得到了这个。似乎参数(由孩子创建的对象)在孩子关闭自己时立即被释放,尽管它​​已经传递给父母,但在孩子关闭后父母无法访问它
2021-04-04 08:39:10