`setTimeout`,通过字符串传递,返回错误

时间:2015-06-09 23:35:35

标签: javascript html css3

这是两段相同的代码;但第一个正常工作:

function dismiss(obj) {setTimeout(function() {obj.style.display = "none";}, 20);}

而第二个返回error: obj is not defined

function dismiss(obj) {setTimeout('obj.style.display = "none"', 20);}

为什么会这样?
P.S。: An example

4 个答案:

答案 0 :(得分:4)

答案在于closuresor more in depth

在第一个示例中,创建匿名函数时捕获obj变量。运行该功能时,捕获的obj引用用于访问style,该工作正常。

然而在第二种情况下,没有关闭,因为字符串是在<{em} eval内的setTimeout 中运行的,如Mozilla documentation所述,将执行在全球范围内:

  

在全局上下文中计算字符串文字,因此当字符串被计算为代码时,调用setTimeout()的上下文中的局部符号将不可用。

全局上下文不包含obj变量,这会导致&#34;未定义&#34; 错误。

答案 1 :(得分:2)

obj仅存在于dismiss()函数的范围内以及其中的所有内容中。第一个语句定义了一个函数,因此它可以引用它。第二个语句在该范围之外执行,不能引用它。

答案 2 :(得分:1)

来自documentation

Code executed by setTimeout() is run in a separate execution context to the function from which it was called. As a consequence, the this keyword for the called function will be set to the window (or global) object; it will not be the same as the this value for the function that called setTimeout.

在这两个示例中,超时代码的范围是全局上下文,或window

在第一个示例中,上下文无关紧要,因为在触发超时之前不评估obj.style.display。那时,obj具有最初传递给dismiss的任何值,一切正常。

在第二个示例中,代码立即执行,其中obj在全局window范围内未定义(或者如果已定义,则不是您期望的那样),所以你有效地生成了这段代码:

function dismiss(obj) {setTimeout(function ()  { undefined = "none" }, 20);}

答案 3 :(得分:-6)

正确的代码应如下所示:

function dismiss(obj) {setTimeout(obj.style.display = "none", 20);}

因为您在'的第一个和最后一个添加obj.style.display = "none"所以它将成为一个字符串。