代码之家  ›  专栏  ›  技术社区  ›  Dimitar Christoff

通过setinterval/settimeout访问eval'd代码

  •  0
  • Dimitar Christoff  · 技术社区  · 14 年前

    我想知道我是否可以做一些自动抓取超时/间隔的清理例程。考虑一下:

    var timeout = setInterval(function dimitar() {
        console.log("hi!");
    }, 1000);
    
    console.log(window);
    

    我看了一下窗口,找不到任何对已传递函数的引用。对超时的引用就在这里,这是足够肯定的。那么,函数“活”在哪里呢?它是否启动了JS解释器的新实例来eval/run/keep代码?如何根据超时uid访问它?

    我知道我可以利用setinterval函数并让它总是将引用存储到一个数组中,然后我可以循环并清除该数组,但是我很好奇是否有一种自然的方法可以做到这一点

    2 回复  |  直到 14 年前
        1
  •  1
  •   bobince    14 年前

    那么,函数“活”在哪里呢?

    超时/间隔队列是内容javascript无法访问的内部实现细节。它保留对传入到的函数的引用 setInterval 但你看不到它是一个参考。

    顺便说一下,通常应避免使用命名的内联函数表达式。虽然在这个示例代码中可能没有问题,但是ie的jscript有一些严重的基本错误,如果不小心的话,这些错误会使您陷入困境。坚持使用命名函数语句( function dimitar() { ... } ... setInterval(dimitar, 1000) )或匿名内联函数表达式( setInterval(function() { ... }) )

    它是否启动了JS解释器的新实例来eval/run/keep代码?

    不,它是同一个解释器,队列甚至可以用JavaScript实现。但是它背后的变量被隐藏在远离调用者的地方。

    如何根据超时uid访问它?

    超时ID的设计完全不透明。唯一可以对其执行任何操作的定义接口是 clearTimeout / clearInterval 打电话。没有提供从超时ID获取函数的接口。

        2
  •  2
  •   Tim Down    14 年前

    您在示例中创建的函数使用 命名函数表达式 . 该名称仅在函数中可用。否则,它的行为与匿名函数相同:您没有将它赋给变量,而且由于它不是函数声明,因此它不会创建 dimitar 封闭范围中的变量。以下文章可能有用: http://yura.thinkweb2.com/named-function-expressions/

    没有 eval -输入正在进行的事情:您刚刚将对函数的引用传递到 window.setInterval . 除非您以前已将此函数分配给变量,或者它是对由函数声明定义的函数的引用,否则以后无法检索此函数。

    如果您想在函数周围保留一个引用,只需先将其存储在变量中即可:

    var dimitar = function() {
        console.log("hi!");
    };
    
    window.setInterval(dimitar, 1000);