浏览器是否持久缓存脚本元素的编译版本

Does the browser persistently cache compiled versions of script elements?

本文关键字:元素 编译 版本 脚本 缓存 是否 浏览器      更新时间:2023-09-26

在一个允许用户玩javascript的web应用程序中,我要求他们在"程序"中有一个function main()。有一个"运行"按钮和一个"编辑"按钮。当您按下"run"时,<textarea>中的文本用于创建脚本块并将其插入DOM。然后调用CCD_ 3。

我捕获window.onerror以向用户显示错误。这通常工作正常。如果没有main(),则会显示相应的错误消息。

当您按下"编辑"时,脚本块被设置为空白(script.text = '';),并从DOM中删除。

测试时,我注意到,如果我有一个"程序",只包括:

function main() { printLn('main here'); }

它按预期工作,但当我把它改为:

function moon() { printLn('moon here'); }

尽管脚本块有"月亮"文本,但它仍然像以前一样工作,而不是收到一条说main() not defined的消息。如果我给每个创建的脚本块一个独特的ID,并且在删除之前将脚本块类型更改为text/plain,这种情况就会继续发生。

该问题出现在当前的Firefox、Chrome和Opera中。您可以在这里看到发生了什么

即使删除了定义函数的脚本,函数仍然被定义。

这与CSS形成了鲜明对比,在CSS中,删除或修改样式表将相应地删除或更新页面上的样式。

这有一个很好的理由,那就是CSS被设计成在进行更改时可以很容易地重新评估。另一方面,JavaScript太复杂了,浏览器无法理解"删除脚本"的实际作用。

所以,如果你用main()运行了一个函数,即使你删除了它,它也会继续存在

我的建议是创建一个闭包来运行脚本。你可以用这样的东西来做。。。

var input = "........"; // user's input
var runner = "if( typeof main === 'undefined') {"+
    "showErrorMessage('No main() defined');"+ // or whatever your error function is
  "} else { main(); }";
var func = new Function("(function() {"+input+runner+"})()");
func();

值得注意的是,全局作用域仍然可以访问,例如,如果用户忘记了var他们的局部变量,或者如果他们直接访问window.something。只要它只在用户自己的机器上运行,这就不是什么大问题,但如果人们可以与他人共享他们的代码,那么你就需要更加小心。