【问题标题】:Removed JavaScript is still executable删除的 JavaScript 仍然可以执行
【发布时间】:2015-05-03 21:44:04
【问题描述】:

如果我有以下 JavaScript 代码:

<script id="someJS">

    var boom = 'boom';

    function example(){

        alert(boom);
    }

</script>

然后做:

$('#someJS').remove();

即使该 JavaScript 函数不再位于 DOM 内,我仍然可以调用 example()...如何删除它?

我不想将实际函数和变量设为:boom = null; example = null;,因为我并不总是知道 JavaScript 文件中的内容。例如函数名称、变量等。我需要能够删除该脚本标签内的全部内容。


更新:对于那些想了解此用户案例的人:

基本上在我正在开发的应用程序中,我们为某些客户端添加了自定义 JavaScript,当单击按钮时,例如保存,然后检查某些函数是否存在,然后运行它们。然而,由于这个保存按钮是通用的,这意味着自定义代码在添加后会一直被调用,即使它不再相关。

我们提出的解决方案(有人将此作为答案发布,但他们出于某种原因将其删除)是将其全部命名为:

DynamicJS = {

    boom: 'boom',

    example: function(message) {

        alert(message);

    }

}

然后我们可以这样做:delete DyanmicJS;

这会从全局范围中删除此命名空间内的所有函数和变量,从而有效地将脚本文件添加的内容分箱。

虽然我确信这不是一个完美的解决方案,就好像文件中有事件侦听器一样,但我确信它们仍然存在!

【问题讨论】:

  • “我不想让实际函数为空,因为我并不总是知道 JS 文件中的内容。” 你到底是什么意思?
  • 如example= null;
  • 为什么还要删除一个函数?仍然拥有它的负面影响是什么?
  • 这将是唯一的方法
  • 下面有一些答案可以满足您的要求...但我可能会提出真正的问题是什么? meta.stackexchange.com/a/66378/278651

标签: javascript jquery


【解决方案1】:

我怎样才能删除它?我不想让实际函数为空,因为我并不总是知道 JS 文件中的内容。

你不能。脚本代码被执行,在 JavaScript 环境中创建东西,并且与加载它的 script 元素完全断开。除了完全重新加载该环境之外,如果您不知道代码做了什么,则无法撤消它。

即使您可以推断出代码所做的一些事情(例如,通过列出前后的全局变量),但您可以删除检测到的新全局变量(或至少将它们设置为 null 或 @987654323 @,因为 delete 不适用于通过函数声明或 var 添加的全局变量,这并不能告诉您代码可能连接了哪些事件处理程序、网络工作者等。

【讨论】:

  • 这可能是这里最合适的答案,尤其是与 OP 的要求相关:如果您不知道代码做了什么,则无法撤消它。
  • @RGraham 或者,简而言之:您无法取消运行已经运行的内容。
【解决方案2】:

$('#someJS').remove(); 仅从页面中删除脚本元素。
当元素被移除时,脚本已经被解释,这意味着example 已经被添加到全局作用域中。

要正确删除该功能,您可以这样做:

window.example = null;

但是,显然您不想这样做,如果其他地方有实际使用 example 的脚本,这将导致大量错误。

另一种方法是为其分配一个空函数:

window.example = function(){};

这将防止“删除”导致错误。
(除了函数在预期时不返回值)

【讨论】:

    【解决方案3】:

    处理完函数后,它现在是 window 的可执行函数列表的一部分 - 无论您是否删除原始源。

    要完全删除该功能,请尝试:

    window['example'] = null;
    

    但是,根据您上次的评论:

    我不想让实际函数为空,因为我并不总是知道 JS 文件中的内容。

    听起来您想保持对该函数的引用,但不让它直接可执行?如果是这种情况,您可以存储对它的引用并删除原始引用:

    var _exampleBackup = window['example'];
    window['example'] = null;
    

    要调用它,您现在可以使用:

    _exampleBackup();
    

    如果需要,还可以恢复它:

    window['example'] = _exampleBackup;
    example();
    

    【讨论】:

    • 显然,this is exactly what the OP doesn't want。 (出于某种原因...)
    • @Cerbrus 哇,完全错过了最后一条评论!刚刚更新了我对地址的回答 - 非常感谢您指出...总 *facepalm* 时刻 =P
    • 应该更清楚一点,“一旦函数被处理”是指&lt;script&gt;标签和它的内容正在被处理,而不是(正如人们可能解释的那样)函数已经被叫。 - 有趣的是,OP 的remove() 可以安全地从被“删除”的脚本内调用
    【解决方案4】:

    该功能仍在窗口中。

    您放入脚本标签中的代码将在创建元素时运行,并且本身不再具有(大致)价值。移除标签不会影响文档及其对文档的影响(通常)。

    要删除该函数,您需要删除window 对象上的example 属性,这是定义函数的方式,运行上面的代码。

    【讨论】:

    • 我要吹毛求疵:函数的存储位置与“DOM”无关。它存储在global execution context
    • @Cerbrus 恰好是浏览器中的窗口:P
    • 你真的必须回复我5年前留下的评论吗?
    • @Cerbrus 是的,我很忙,抱歉。
    【解决方案5】:

    为了删除该函数,您可以将其设置为null 或简单地用example=function(){}; 覆盖它

    【讨论】:

      【解决方案6】:

      JavaScript Hoisting

      JavaScript中有一个概念叫做Hoisting。在这个阶段,编译器解析所有 JavaScript 代码并在作用域的开头声明变量和函数。在您的情况下,函数示例和变量 boom 已经声明并保存在内存中。当您运行该方法时,解释器将调用该方法并解释它,而不是解释实际的 JavaScript 代码。您将在脚本块进入内存后删除它。这就是为什么它仍然是可执行的。

      实现此目的的方法

      1) 使用面向对象的方法。在对象中添加您的方法,当您想删除它时,使用delete 删除该属性。 2) 创建一个变量,该变量包含一个包含要执行的代码的函数,并在需要时将该变量设置为未定义。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-12-11
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多