for(var i=0;i<=3;i++){ setTimeout(function() { consolelog(i) }, 10);}
答案:打印4次4
这道题涉及了异步、作用域、闭包
settimeout是异步执行,10ms后往任务队列里面添加一个任务,只有主线上的全部执行完,才会执行任务队列里的任务,当主线执行完成后,i是4,所以此时再去执行任务队列里的任务时,i全部是4了。对于打印4次是:
每一次for循环的时候,settimeout都执行一次,但是里面的函数没有被执行,而是被放到了任务队列里面,等待执行,for循环了4次,就放了4次,当主线程执行完成后,才进入任务队列里面执行。
(注意:for循环从开始到结束的过程,需要维持几微秒或几毫秒。)
当我把var 变成let 时
for(let i=0;i<=3;i++){ setTimeout(function() { consolelog(i) }, 10);}
打印出的是:0,1,2,3
当解决变量作用域,
因为for循环头部的let不仅将i绑定到for循环快中,事实上它将其重新绑定到循环体的每一次迭代中,确保上一次迭代结束的值重新被赋值。setTimeout里面的function()属于一个新的域,通过 var 定义的变量是无法传入到这个函数执行域中的,通过使用 let 来声明块变量,这时候变量就能作用于这个块,所以 function就能使用 i 这个变量了;这个匿名函数的参数作用域 和 for参数的作用域 不一样,是利用了这一点来完成的。这个匿名函数的作用域有点类似类的属性,是可以被内层方法使用的。
查了一下百度的一个答案:
setTimeout是一次执行函数,这里是10ms后执行,仅仅执行一次;for(var i=0;i<=3;i++),i的每次取值都是执行setTimeout这个函数,并没有执行setTimeout里面的function(即闭包函数),setTimeout里面的function是有setTimeout的定时触动的,也就是10ms后执行,也就是说i从0~3时,一共执行了4次的setTimeout()函数,此时的i的值是4,由于for语句的执行速度远小于1秒,所以,1秒后,由setTimeout()函数定时触动的闭包函数function()开始执行,alert(i);i的值已经是4了,所以相继打印4次i
https://wwwcnblogscom/wangwenhui/p/7657654html
setTimeout是一次执行函数,这里是1秒后执行,仅仅执行一次;for(var i=0;i<10;i++),i的每次取值都是执行setTimeout这个函数,并没有执行setTimeout里面的function(即闭包函数),setTimeout里面的function是有setTimeout的定时触动的,也就是1秒后执行,也就是说i从0~9时,一共执行了10次的setTimeout()函数,此时的i的值是10,由于for语句的执行速度远小于1秒,所以,1秒后,由setTimeout()函数定时触动的闭包函数function()开始执行,alert(i);i的值已经是10了,所以相继打印10次i
1setTimeout
是延迟一段时间后执行函数。
2setInterval
是每间隔一段时间就执行该函数。但是如果函数的执行时间超过设置的间隔时间,会出现函数小于间隔时间而执行或无间隔执行的情况。
3如果用setTimeout的进行递归调用来模拟setInterval。这样函数执行的间隔时间就会保证(>=设置时间)。
结论:如果要确保函数执行的间隔时间,建议用setTimeout
递归调用来代替setInterval。
性能方面不太清楚。详细的话你可以去后盾网去看看的,哪里都有讲师教学,讲的都很详细。
返回该计时器的ID,停止计时器的时候会用到。
141 setTimeout和setInterval的使用
这两个方法都可以用来实现在一个固定时间段之后去执行JavaScript。不过两者各有各的应用场景。
方 法
实际上,setTimeout和setInterval的语法相同。它们都有两个参数,一个是将要执行的代码字符串,还有一个是以毫秒为单位的时间间隔,当过了那个时间段之后就将执行那段代码。
不过这两个函数还是有区别的,setInterval在执行完一次代码之后,经过了那个固定的时间间隔,它还会自动重复执行代码,而setTimeout只执行一次那段代码。
虽然表面上看来setTimeout只能应用在on-off方式的动作上,不过可以通过创建一个函数循环重复调用setTimeout,以实现重复的 *** 作:
File: settimeout_setintervaljs
showTime();
function showTime()
{
var today = new Date();
alert("The time is: " + todaytoString());
setTimeout("showTime()", 5000);
}
一旦调用了这个函数,那么就会每隔5秒钟就显示一次时间。如果使用setInterval,则相应的代码如下所示:
File: settimeout_setinterval2js
setInterval("showTime()", 5000);
function showTime()
{
var today = new Date();
alert("The time is: " + todaytoString());
}
这两种方法可能看起来非常像,而且显示的结果也会很相似,不过两者的最大区别就是,setTimeout方法不会每隔5秒钟就执行一次showTime函数,它是在每次调用setTimeout后过5秒钟再去执行showTime函数。这意味着如果showTime函数的主体部分需要2秒钟执行完,那么整个函数则要每7秒钟才执行一次。而setInterval却没有被自己所调用的函数所束缚,它只是简单地每隔一定时间就重复执行一次那个函数。
如果要求在每隔一个固定的时间间隔后就精确地执行某动作,那么最好使用setInterval,而如果不想由于连续调用产生互相干扰的问题,尤其是每次函数的调用需要繁重的计算以及很长的处理时间,那么最好使用setTimeout。
函数指针的使用
两个计时函数中的第一个参数是一段代码的字符串,其实该参数也可以是一个函数指针,不过Mac下的IE 5对此不支持。
如果用函数指针作为setTimeout和setInterval函数的第二个参数,那么它们就可以去执行一个在别处定义的函数了:
setTimeout(showTime, 500);
function showTime()
{
var today = new Date();
alert("The time is: " + todaytoString());
}
另外,匿名函数还可以声明为内联函数:
setTimeout(function(){var today = new Date();
alert("The time is: " + todaytoString());}, 500);
讨 论
如果对计时函数不加以处理,那么setInterval将会持续执行相同的代码,一直到浏览器窗口关闭,或者用户转到了另外一个页面为止。不过还是有办法可以终止setTimeout和setInterval函数的执行。
当setInterval调用执行完毕时,它将返回一个timer ID,将来便可以利用该值对计时器进行访问,如果将该ID传递给clearInterval,便可以终止那段被调用的过程代码的执行了,具体实现如下:
File: settimeout_setinterval3js (excerpt)
var intervalProcess = setInterval("alert('GOAL!')", 3000);
var stopGoalLink = documentgetElementById("stopGoalLink");
attachEventListener(stopGoalLink, "click", stopGoal, false);
function stopGoal()
{
clearInterval(intervalProcess);
}
只要点击了stopGoalLink,不管是什么时候点击,intervalProcess都会被取消掉,以后都不会再继续反复执行intervalProcess。如果在超时时间段内就取消setTimeout,那么这种终止效果也可以在setTimeout身上实现,具体实现如下:
File: settimeout_setinterval4js (excerpt)
var timeoutProcess = setTimeout("alert('GOAL!')", 3000);
var stopGoalLink = documentgetElementById("stopGoalLink");
attachEventListener(stopGoalLink, "click", stopGoal, false);
function stopGoal()
{
clearTimeout(timeoutProcess);
}
setTimeout(function(){
for(var i=0;i<lstArrlength;i++){
//code
}
alert(index);
},1000);
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)