为了账号安全,请及时绑定邮箱和手机立即绑定

关于最后的立即执行函数和d.onreadystatechange=function(){}不知这样理解是否有错?

这是我的理解,请大神来指正,否则我真的不知道该怎么理解这些代码了。(前边一些代码略去)首先开始立即执行函数,在这个立即执行函数里是DOM树创建完成的判断(它和window.onload有很大区别,前者是创建DOM树,onload是不仅树可能创建完了,还有可能正在加载外部信息),如果DOM树创建完成跳过try catch执行init()也就是css样式设置为红色,如果没有创建完毕,则执行try中的doSCroll捕获错误并执行catch中的setTimeout,接着利用return跳过该立即执行函数接下来浏览器继续加载,而代码执行到d.onreadystatechange=function(){}进行监听,这种情况下假设30ms进入立即执行函数而48msDOM树建立完毕,还差18msDOM树才能建好,于是执行了Timesetout并跳出了立即执行函数,再假设49ms网页加载完毕,而刚好进入d.onreadystatechange=function(){}的时间是49ms,即dom树建立完毕网页加载完毕;由于49ms<Settimeout中的50ms因而执行了d.onreadystatechange=function(){}中的init函数,于是这是在网页加载完毕的前提下将CSS设置为红色。情况二:我们依旧假设48msDOM树建立完毕,但是网页加载完是51ms,进入立即执行函数的时间是30ms此时30ms<48ms<50ms这意味DOM树没有建立,继续进入到d.onreadystatechange=function(){}时间为48ms,由于网页未加载完,但时间已经走入到了50ms开始执行setTimeout这个递归,此时50ms>48ms(另一边网页加载也在进行)DOM树已经建立完毕,这时执行立即调用函数里的init(),而后网页加载完成了。

也就是说2个init()分别对应DOM树建立好了,而网页不一定加载完的情况下调用init(),和网页以及DOM树都加载好了后调用init()函数这2种大情况?

闲话太多,望大神给个评价我的理解方式是否正确?

正在回答

2 回答

1,onload事件不是有可能正在加载外部信息,而是必须等外部数据全部加载完才能触发。

2,return是用来跳出setTimeout所创建的递归函数的外层,在外层阻止运行init(),但是当这个递归执行到调用doScroll不抛出错误的时候(也就是DOMReady的时候)就没有return了,此时会执行一次init()。而不是题住理解的return直接跳过了一次性函数去执行后面的readystatechang事件监听。因此,只要顺利,这个一次性函数里的init()是一定会被调用一次的。而且实际应用中setTimeout的第二次参数是0(浏览器最短时间内重复执行)而不是50。

3,d.onreadystatechange=function(){}是绑定事件处理函数,这个绑定过程是在函数编译的时候就完成的,至于触发这个事件,则是document.readyState发生变化时触发,因此题主的表述是有点问题的,当readyState为"complete"时,这个事件监听函数里的init()也是一定会被调用一次的。

综合2和3,确实是在比两个逻辑谁快,但理论上肯定是2的逻辑更快,至于为什么要有3,我印象中是为了应付没有实现DOMContentLoaded也没有document.documentElement.doScroll在DOM没准备好时会报错的特性(这个特性只有低版本的IE有)的非IE浏览器准备的。


以上是我的理解,欢迎指正~

1 回复 有任何疑惑可以回复我~
#1

慕粉3988711 提问者

答案3我看了老师后边的视频,如您所说;对于答案2的return;由于JS基础,JS进阶以及深入浅出JS都没有细讲return;于是我百度了下return;这意味着return会退出当前函数,但是由于没有Ready,catch中的递归会无限次的调用这个立即函数,除非你设置了条件(譬如if判断等)跳出递归,但是假设Ready完毕,递归再次进入try块发现doScroll为true,于是会跳过catch执行init()并跳出立即执行函数,我想问一下return在这次代码中可以不用啊,为什么还要加return啊?
2016-10-30 回复 有任何疑惑可以回复我~
#2

慕粉3988711 提问者

我又想了一下,假设进入立即函数为1,try为2,catch为3,init为4,立即执行函数进行了2次发现DOMReady再执行init(),那么顺序是123-124,由于return需要按层次返回调用的函数而且调用函数正是函数本身所以还有个返回过程为421-321然后才真正的跳出这个立即执行函数,请问这样理解return 对不对?
2016-10-30 回复 有任何疑惑可以回复我~
#3

慕粉3988711 提问者

非常感谢!
2016-10-31 回复 有任何疑惑可以回复我~
#4

姜素源3788549

讲的真好!
2017-01-26 回复 有任何疑惑可以回复我~
查看1条回复

上面的表述有点语病,重新整理了一下,去掉了题主问题中本身表述有误的部分。

1,return是用来跳出setTimeout所创建的递归函数的外层,在外层阻止运行init(),但是当这个递归执行到调用doScroll不抛出错误的时候(也就是DOMReady的时候)就没有return了,此时会执行一次init()。因此,只要顺利,这个一次性函数里的init()是一定会被调用一次的。而且实际应用中setTimeout的第二次参数是0(浏览器最短时间内重复执行)而不是50。

2,d.onreadystatechange=function(){}是绑定事件处理函数,这个绑定过程是在函数编译的时候就完成的,运行过程中document.readyState发生变化时会触发事件来运行调用监听函数,当readyState为"complete"时,这个事件监听函数里的init()也是一定会被调用一次的。

综合1和2,有点像是在比谁更快,但理论上肯定是1的更快,至于为什么要有2,我印象中是为了应付没有实现DOMContentLoaded也没有document.documentElement.doScroll在DOM没准备好时会报错的特性(这个特性只有低版本的IE有)的非IE浏览器的,而不是两个逻辑代码都是为低版本IE准备的。


3 回复 有任何疑惑可以回复我~

举报

0/150
提交
取消

关于最后的立即执行函数和d.onreadystatechange=function(){}不知这样理解是否有错?

我要回答 关注问题
意见反馈 帮助中心 APP下载
官方微信