我正在读你不懂JS书系列。
在范围&的第5章中。这本书的关闭标题,这个for循环我无法理解
for (var i=1; i<=5; i++) {
setTimeout( function timer(){
console.log( i );
}, i*1000 );}
在1秒间隔后,它在控制台中打印6次。 甚至作者也试图解释为什么会发生这种情况,但我无法得到他想说的话。
您可以在此处找到此代码的解释: https://github.com/getify/You-Dont-Know-JS/blob/master/scope%20%26%20closures/ch5.md
前往&循环+关闭&#39;您将在页面上找到此代码。
任何人都可以用简单的语言解释我吗? 为什么它在控制台中打印6次5次而不是1次,2次,...,5秒后间隔。
先谢谢你的时间和时间。努力。
答案 0 :(得分:3)
是的,因为循环在第二个循环中运行,那时i的值是6(,最后一个i ++没有进入循环)。因此它使用 该值要渲染5次。
您可以使用以下内容打印1,2,3,4,5
for (let i=1; i<=5; i++) {
setTimeout( function timer(){
console.log( i );
}, i*1000 );}
使用let
定义i的范围,该范围是ES6
答案 1 :(得分:1)
这种情况发生是因为SetTimeoutFunction中还有另一个范围。
如果您使用ES6,您可以看到1 2 3 4 5。
for (let i=1; i<=5; i++) {
setTimeout( function timer(){
console.log( i );
}, i*1000 );
}
这里使用let创建特殊变量,可以在SetTimeout范围内使用。
答案 2 :(得分:1)
这里存在简单逻辑。第一次进入循环并调用定时器功能。但定时器功能将等待1秒钟。在这1秒内,for循环将执行所有6次,最后是i = 6中的值。
和计时器功能也会在一秒内执行6次。
在定时器仅执行第一次之前i = 6中的值。 同样地,这个我的值也是接下来的5倍。
如果您只想更改代码,请按照以下方式
for (var i=1; i<=11; i++) {
setTimeout( function timer(){
console.log( i );
}, i*1000 );}
然后它打印11次10次
答案 3 :(得分:0)
循环在您启动后立即运行,并将6
的值增加到i
。 setTimeout中的回调函数在此之后运行1到5秒,并打印6
的实际值,始终为6
,因为循环在第0秒将其设置为library(dplyr)
library(plm)
data(Cigar)
model_plm <- plm(price ~ sales, index = c("state"), model = "within", data = Cigar)
summary(model_plm)
C <- cbind(seq(100,150,10))
pred <- expand.grid(sales = C)
pred$fixef <- mean(fixef(model_plm))
pred$b_sales <- coef(summary(model_plm))[1]
pred$yhat <- with(pred, sales*b_sales + fixef)
pred$yhat_se <- sqrt((diag(C%*%vcov(model_plm)%*%t(C))))
pred <- mutate(pred, lwr=yhat-1.96*yhat_se, upr=yhat+1.96*yhat_se)
pred
。 / p>
答案 4 :(得分:0)
因为i
是在setTimeout
执行的函数的上下文之外定义的,所以当达到超时时,i
的值为6,因此所有超时都将执行该函数并打印i
的当前值。
正如你所说,章节的标题是Closures
,你可以使用闭包来解决这个问题。
for (var i=1; i<=5; i++) {
//This is a IIFE (Immediately-invoked function expression)
//Simply put, a function that will be executed right after its definition
(function(curr) {
setTimeout( function timer(){
console.log( curr );
}, i*1000 );}
})(i)
}
在上面的示例中,curr
变量包含在该上下文中,并将保存调用函数时使用的值。
答案 5 :(得分:0)
让我一步一步解释:
for (let i=1; i<=5; i++) {
setTimeout( function timer(){
console.log( i );
}, i*1000 );}
第一次迭代:
我是1, 第一个计时器设置为1 * 1000 = 1秒第二次迭代:
我是2岁, 第二个计时器设置为2 * 1000 = 2秒第3次迭代:
我是3岁, 第3个定时器设置为3 * 1000 = 3秒第4次迭代:
我是4岁, 第4个定时器设置为4 * 1000 = 4秒第5次迭代:
我是5岁, 第5个定时器设置为5 * 1000 = 5秒当我变为6时,它退出循环,所以现在我们有5个定时器,时间分别为1,2,3,4和5秒,i的当前值为6.所有定时器都已设置但没有执行因为1秒还没有过去。
1秒后,第1个计时器结束,打印6个 2秒后,第二个计时器结束,打印6个 等等....
因此你得到一个输出:66666,每个间隔为1秒,但实际的计时器值是1,2,3,4和5秒