这是两段相同的代码;但第一个正常工作:
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
答案 0 :(得分:4)
答案在于closures,or more in depth。
在第一个示例中,创建匿名函数时捕获obj
变量。运行该功能时,捕获的obj
引用用于访问style
,该工作正常。
然而在第二种情况下,没有关闭,因为字符串是在<{em} eval
内的setTimeout
中运行的,如Mozilla documentation所述,将执行在全球范围内:
在全局上下文中计算字符串文字,因此当字符串被计算为代码时,调用setTimeout()的上下文中的局部符号将不可用。
全局上下文不包含obj
变量,这会导致&#34;未定义&#34; 错误。
答案 1 :(得分:2)
obj
仅存在于dismiss()
函数的范围内以及其中的所有内容中。第一个语句定义了一个函数,因此它可以引用它。第二个语句在该范围之外执行,不能引用它。
答案 2 :(得分:1)
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"
所以它将成为一个字符串。