摘要:閉包在循環中的應用延遲函數的回調會在循環結束時才執行事實上,當定時器運行時即使沒給迭代中執行的是多有的回調函數依然是在循環結束后才會被執行,因此會每次輸出一個出來。
閉包在循環中的應用
延遲函數的回調會在循環結束時才執行;
事實上,當定時器運行時即使沒給迭代中執行的是 setTime(..., 0),多有的回調函數依然是在循環結束后才會被執行,因此會每次輸出一個6出來。
for(var i=1; i<=5; i++){ setTimeout( function timer(){ let temp = new Date(); console.log(i + "----" + temp.toLocaleTimeString() + "." + temp.getMilliseconds()); }, i*1000); if(i == 5){ var now = new Date(); console.log("for循環結束----"+now.toLocaleTimeString() + "." + now.getMilliseconds()); } } // for循環結束----下午7:51:29.885 // 6----下午7:51:30.885 // 6----下午7:51:31.885 // 6----下午7:51:32.885 // 6----下午7:51:33.885 // 6----下午7:51:34.885利用立即執行函數創建作用域,但作用域為空(沒有傳參),并未奏效;
for (var i = 0; i <= 5; i++){ (function(){ setTimeout(function timer(){ let temp = new Date(); console.log(i + "----" + temp.toLocaleTimeString() + "." + temp.getMilliseconds()); }, i*1000) })(); if(i == 5){ var now = new Date(); console.log("for循環結束----"+now.toLocaleTimeString() + "." + now.getMilliseconds()); } }在立即執行函數中捕獲一個變量
for (var i = 0; i <= 5; i++){ (function(){ var j = i; // IIFE有了自己的變量 setTimeout(function timer(){ let temp = new Date(); console.log(j + "----" + temp.toLocaleTimeString() + "." + temp.getMilliseconds()); }, j*1000) })(); if(i == 5){ var now = new Date(); console.log("for循環結束----"+now.toLocaleTimeString() + "." + now.getMilliseconds()); } } // for循環結束----下午8:14:28.915 // 0----下午8:14:28.916 // 1----下午8:14:29.916 // 2----下午8:14:30.916 // 3----下午8:14:31.916 // 4----下午8:14:32.916 // 5----下午8:14:33.916改進 1. 利用立即執行函數(IIFE)傳參
利用立即執行函數為每個迭代都生成一個新的作用域,使得延遲函數的回調可以將新的作用域封閉在每個迭代內部;
for (var i = 0; i <= 5; i++){ (function(j){ setTimeout(function timer(){ let temp = new Date(); console.log(j + "----" + temp.toLocaleTimeString() + "." + temp.getMilliseconds()); }, j*1000) })(i); }2. 利用setTimeout給回調函數(callback)中傳參,產生timer對for循環作用域的閉包
利用延遲函數向其回調函數中傳參,為每個迭代中callback中生成新的作用域,使得延遲函數的回調可以將新的作用域封閉在每個迭代內部;
for (var i = 0; i <= 5; i++){ setTimeout(function timer(j){ let temp = new Date(); console.log(j + "----" + temp.toLocaleTimeString() + "." + temp.getMilliseconds()); }, i*1000, i); }3. 利用let聲明劫持塊作用域
本質:將一個塊轉換成了一個可以被關閉的作用域。
for(var i=0; i<5; i++){ let j = i;// 閉包的塊作用域 setTimeout(function timer(){ console.log(j); }, j*1000); }4. 利用for循環頭部的let聲明
for循環頭部的let聲明的特殊行為:使得變量i在循環過程中不止被聲明一次,每次迭代都會聲明。
隨后的每個迭代都會使用上一個迭代結束時的值來初始化這個變量。
for(let i=0; i<5; i++){ setTimeout(function timer(){ console.log(i); }, i*1000); }
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/99227.html
摘要:的分句會創建一個塊作用域,其聲明的變量僅在中有效。而閉包的神奇作用是阻止此事發生。依然持有對該作用域的引用,而這個引用就叫做閉包。當然,無論使用何種方式對函數類型的值進行傳遞,當函數在別處被調用時都可以觀察到閉包。 date: 16.12.8 Thursday 第一章 作用域是什么 LHS:賦值操作的目標是誰? 比如: a = 2; RHS:誰是賦值操作的源頭? 比如: conso...
摘要:比如程序會被分解為解析語法分析將詞法單元流轉換成一個由元素逐級嵌套所組成的代表了程序語法接口的書,又稱抽象語法樹。代碼生成將抽象語法樹轉換為機器能夠識別的指令。 showImg(https://segmentfault.com/img/remote/1460000009682106?w=640&h=280); 本文首發在我的個人博客:http://muyunyun.cn/ 《你不知道的...
摘要:注此讀書筆記只記錄本人原先不太理解的內容經過閱讀你不知道的后的理解。作用域及閉包基礎,代碼運行的幕后工作者引擎及編譯器。 注:此讀書筆記只記錄本人原先不太理解的內容經過閱讀《你不知道的JS》后的理解。 作用域及閉包基礎,JS代碼運行的幕后工作者:引擎及編譯器。引擎負責JS程序的編譯及執行,編譯器負責詞法分析和代碼生成。那么作用域就像一個容器,引擎及編譯器都從這里提取東西。 ...
摘要:異步請求線程在在連接后是通過瀏覽器新開一個線程請求將檢測到狀態變更時,如果設置有回調函數,異步線程就產生狀態變更事件,將這個回調再放入事件循環隊列中。 基礎:瀏覽器 -- 多進程,每個tab頁獨立一個瀏覽器渲染進程(瀏覽器內核) 每個瀏覽器渲染進程是多線程的,主要包括:GUI渲染線程 JS引擎線程 也稱為JS內核,負責處理Javascript腳本程序。(例如V8引擎) JS引擎線程負...
摘要:但是如果非全局的變量如果被遮蔽了,無論如何都無法被訪問到。但是如果引擎在代碼中找到,就會完全不做任何優化。結構的分句中具有塊級作用域。第四章提升編譯器函數聲明會被提升,而函數表達式不會被提升。 本書屬于基礎類書籍,會有比較多的基礎知識,所以這里僅記錄平常不怎么容易注意到的知識點,不會全記,供大家和自己翻閱; 上中下三本的讀書筆記: 《你不知道的JavaScript》 (上) 讀書筆記...
閱讀 1668·2023-04-26 00:30
閱讀 3145·2021-11-25 09:43
閱讀 2868·2021-11-22 14:56
閱讀 3183·2021-11-04 16:15
閱讀 1137·2021-09-07 09:58
閱讀 2014·2019-08-29 13:14
閱讀 3101·2019-08-29 12:55
閱讀 982·2019-08-29 10:57