setTimeOut的第一个参数
发布日期:2021-05-06 23:22:04 浏览次数:18 分类:精选文章

本文共 2359 字,大约阅读时间需要 7 分钟。

图1:setTimeOut语法【1】

setTimeout的第一个参数分为3类,1.字符串代码 2.method 3.function【2】 。

 

1.字符串

function display(obj){    obj.style.display='none';    window.setTimeout("obj.style.display='inline'", 500);}

上面的这个代码会报错,obj is not defined。

因为setTimeout方法是window的方法,是个全局方法。执行这个方法的代码的作用域环境是window。

obj是当初display方法的参数传进来的,是个局部变量。在window下找不到obj这个变量所以报未定义。

 

2.封装后的方法传入    -   method

function display(obj){    obj.style.display='none';    window.setTimeout("fn(obj)", 5000);}function fn(o){    o.style.display='inline'}

这样写 obj is not defined  

   原因和上面一样的,这儿调用的fn()是全局方法,它的参数obj在全局变量中找不到。

这里有一个注意点就是 window.setTimeout("fn(obj)", 5000);  这一句内的  fn(obj)  双引号双引号去掉以后会立即执行,当然,这个是错误的,举个例子

同时,抛出一个问题【3】

结果是立即输出0,1,2,3,4

【4】(下面是相应问题的回答,我做了部分修改和添加还有验证)网上关于JS预解释的文章也不少,在进入执行上下文阶段的时候函数并不会执行,简单来说就是当你声明这个函数的时候,只要不调用就不会执行,上下文里面只会保存着这个函数的引用,可以看做这个函数保存在内存中,只有到调用的时候函数才会执行。
你在for循环里面实际上相当于定义了5个定时器,但是js是单线程,这五个函数会被放到队列里面等待执行,你的函数内有立即执行函数,像你在for循环里面实际上相当于定义了5个定时器,但是js是单线程,这五个函数会被放到队列里面等待执行。

(function(i) {

return function() {    console.log(i);}

})(i)

但是由于里面是立即执行函数,相当于执行上面一段,所以会立即就执行了,并且把i传了进去,等到这五个函数执行的时候,向上查找i,正好在这个立即调用函数的作用域里面查找到了i,所以会打印出0、1、2、3、4.

建议这样写(这是答主的提议)

 

但我个人建议这样写

每次将i作为参数传到setTimeout函数内(把(i)放在第一个函数后面也是这个原理,但不太严谨)

 

3.将function直接写在第一个参数处

function display(obj){   obj.style.diaplay='none';  window.setTimeout(function(){ obj.style.display='inline';},500);    }

这种写法是把function直接写在了setTimeout的第一个参数位置,这样写就和display()形成了一个闭包。所以setTimeout执行function的时候display的作用域是存在的。

这样就会先去display()的作用域找obj这个变量,obj是当方法的参数传进来的,所以是能找到的。这样就能正确的执行这段代码。

 

PS1:第一个参数如果要用函数,一般要处理为setTimeOut(“function name()” ,time)  (这时理解为匿名函数,也可以在里面直接执行一句话),或者setTimeOut(function name ,time)  或者setTimeOut(function name(){} ,time)  ,setTimeOut(function name() ,time) 意味着执行返回值而不是函数,这时会立即执行函数,之后将返回值传入setTimeout方法

 

PS2: 有关timer=0

事实上,上面的代码并不是立即执行的,这是因为setTimeout有一个最小执行时间,当指定的时间小于该时间时,浏览器会用最小允许的时间作为setTimeout的时间间隔,也就是说即使我们把setTimeout的延迟时间设置为0,被调用的程序也没有马上启动。

不同的浏览器实际情况不同,IE8和更早的IE的时间精确度是15.6ms。不过,随着HTML5的出现,在高级版本的浏览器(Chrome、ie9+等),定义的最小时间间隔是不得低于4毫秒,如果低于这个值,就会自动增加,并且在2010年及之后发布的浏览器中采取一致。

所以说,当我们写为 setTimeout(fn,0) 的时候,实际是实现插队操作,要求浏览器“尽可能快”的进行回调,但是实际能多快就完全取决于浏览器了。

setTimeout(fn, 0)有什么用处呢?其实用处就在于我们可以改变任务的执行顺序!因为浏览器会在执行完当前任务队列中的任务,再执行setTimeout队列中积累的的任务。

通过设置任务在延迟到0s后执行,就能改变任务执行的先后顺序,延迟该任务发生,使之异步执行【5】。

 

 

参考文献

【1】菜鸟联盟  , Window setTimeout() 方法 , 2013

【2】 , ,,  2014.5.6

【3】鱼娟娟, ,   2017.5.20

【4】尹光耀    ,   2018.5.20

【5】技术空间 . setTimeout 使用方法详解 .  . 2017.2.23

上一篇:yyyy-mm-dd yyyymmdd互相转换
下一篇:一个前端JQuery写一个通过clip属性来写的input+select的支持模糊查询的下拉框

发表评论

最新留言

做的很好,不错不错
[***.243.131.199]2025年04月17日 08时15分31秒