亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定

關于最后的立即執行函數和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下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號