javascript执行计时中的奇怪行为
我是一本名为AsyncJavaScript的书,这本书的一个例子试图说明当处理器在同一进程中没有指令执行时,javascript中的事件将被触发。为了证明他的话,他举了一个例子:javascript执行计时中的奇怪行为,javascript,runtime,scope,Javascript,Runtime,Scope,我是一本名为AsyncJavaScript的书,这本书的一个例子试图说明当处理器在同一进程中没有指令执行时,javascript中的事件将被触发。为了证明他的话,他举了一个例子: for (var i = 1; i <= 3; i++) { setTimeout(function(){ console.log(i); }, 0); }; 一切正常,我期待结果。但是,当我将“console.log(i)”退出函数时,结果将会改变 for (var i = 1; i <= 3; i
for (var i = 1; i <= 3; i++) {
setTimeout(function(){ console.log(i); }, 0);
};
一切正常,我期待结果。但是,当我将“console.log(i)”退出函数时,结果将会改变
for (var i = 1; i <= 3; i++) {
setTimeout(console.log(i), 0);
};
我不知道为什么这些例子中的输出是不同的。我知道它是关于变量作用域的,但不知道确切的原因。我希望有人能帮忙
我不知道为什么这些例子中的输出是不同的
因为在第二种情况下,您将立即调用console.log(i)
,并将返回值undefined
传递给setTimeout
(而不是像第一种情况那样传递函数)。参数总是首先求值,因此如果您有
foo(bar())
,则首先调用bar
,并将其返回值传递给foo
您可以通过添加console.log('after')来验证这一点代码>在循环之后。在第一种情况下,你应该
after
4
4
4
在第二种情况下,你会得到
1
2
3
after
演示setTimeout
没有向事件队列添加任何内容
另见
我知道它是关于变量作用域的
实际上,它不是,它是关于时间的,是执行console.log
的时刻
我不知道为什么这些例子中的输出是不同的
因为在第二种情况下,您将立即调用console.log(i)
,并将返回值undefined
传递给setTimeout
(而不是像第一种情况那样传递函数)。
参数总是首先求值,因此如果您有foo(bar())
,则首先调用bar
,并将其返回值传递给foo
您可以通过添加console.log('after')来验证这一点代码>在循环之后。在第一种情况下,你应该
after
4
4
4
在第二种情况下,你会得到
1
2
3
after
演示setTimeout
没有向事件队列添加任何内容
另见
我知道它是关于变量作用域的
实际上,它不是,它是关于计时的,执行console.log
的时刻。当您调用setTimeout(expr,t)
时,expr
得到计算,希望它返回一个函数。在第二种情况下,console.log(…)
不会返回任何内容,但会对其进行评估。您看到的是,在将结果传递给setTimeout
之前,此计算的副作用。当您调用setTimeout(expr,t)
时,expr
将被计算,希望它返回一个函数。在第二种情况下,console.log(…)
不会返回任何内容,但会对其进行评估。在将结果传递给setTimeout
@adeneo之前,您看到的是此评估的副作用:您确定这是完全重复的吗?问题是为什么console.log
的输出不同于setTimeout
@Matt-是的,它是重复的,第一个setTimeout函数创建了一个异步函数作用域,而第二个setTimeout不做任何事情,因为函数没有被引用,而是直接调用。“我不知道为什么这些示例中的输出不同”,因为您正在立即调用console.log(i)
,并将返回值undefined
传递给setTimeout
。参数总是首先求值,因此如果您有foo(bar())
,bar
首先被调用,它的返回值被传递给foo
。另请参见@adeneo:…在链接的副本中没有解释。我已经投票决定重新打开。我的评论是一个答案,但我确定它是一个副本。如果你找到了,请告诉我,或者干脆关闭它。@adeneo:你确定这是一个完全相同的副本吗?T问题是为什么console.log
的输出与setTimeout
@Matt不同-是的,它是重复的,第一个setTimeout函数创建了一个异步函数作用域,而第二个setTimeout不做任何事情,因为函数没有被引用,而是直接调用。”我不知道为什么这些示例中的输出不同,“因为您正在立即调用console.log(i)
,并将返回值undefined
传递给setTimeout
。参数总是首先求值,所以如果您有foo(bar())
,首先调用bar
,它的返回值被传递给foo
。另请参见@adeneo:…这并没有解释在你链接的副本中的什么地方。我已经投票决定重新打开。我的评论是一个答案,但我确信它是一个副本。如果你找到了,请告诉我,或者干脆关闭它。是的。显然这与范围无关。Arguments总是先求值
是准确答案。谢谢。显然这与范围无关。参数总是先求值
是准确答案。谢谢