通过setInterval / setTimeout访问eval'd代码

时间:2010-02-05 11:25:14

标签: javascript

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

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

console.log(window);

我浏览了一下窗口,找不到任何对传递函数的引用。确实存在对超时的引用。那么这个功能在哪里“活着”?它是否启动了js解释器的新实例来eval / run / keep代码?如何根据超时uid访问它?

我知道我可以讨论setInterval函数并让它始终将引用存储到一个数组中,然后我可以循环并清除它,但我很好奇是否有一种自然的方式来做这个

2 个答案:

答案 0 :(得分:2)

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

没有eval类型的事情发生了:你刚刚将一个函数的引用传递给window.setInterval。之后无法检索此函数,除非您先前已将其分配给变量,或者它是对函数声明定义的函数的引用。

如果你想保留对函数的引用,只需先将它存储在变量中:

var dimitar = function() {
    console.log("hi!");
};

window.setInterval(dimitar, 1000);

答案 1 :(得分:1)

  

那么这里的功能“活着”在哪里?

超时/间隔队列是内容JavaScript无法访问的内部实现细节。它保留了对传递给setInterval的函数的引用,但它不是您可以看到的引用。

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

  

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

不,它是相同的解释器,队列甚至可以用JavaScript实现。但它背后的变量远离调用者。

  

如何根据超时uid访问它?

超时ID在设计上完全不透明。唯一可以对其执行任何操作的已定义界面是clearTimeout / clearInterval调用。没有提供接口来从超时ID中恢复功能。