javascript
js for循环_JS 函数的执行时机(深入理解6个6)
定時器:setTimeout()
setTimeout() 方法用于在指定的毫秒數后調用函數或計算表達式提示: 1000 毫秒= 1 秒。 提示: 如果你只想重復執行可以使用 setInterval() 方法。 提示: 使用 clearTimeout() 方法來阻止函數的執行。
語法:setTimeout(x,y,z)
- x 函數function()
- y 時間(time)
- z 參數(會自動傳入第一個參數,也就是函數的參數中) 可省略
因為setTimeout含義是定時器,需要通過設置(觸發)時間來調用代碼
假使設置的時間為3000,則在3000毫秒數彈出對話框“Hello” 假使設置的觸發時間為“0”時,含義則為盡快調用
打個比喻:老板讓你清點運來的箱子,當數到第50個,老板和你說把結果寫到紙上交給我。當下肯定不能進行記錄,因為箱子還未清點完成;只有最后數完箱子后,才能在寫到紙上交給老板
先把主代碼執行完,之后才盡快執行setTimeout中的代碼
JS執行(調用)時機
面試題:6個6
思考:以下代碼會打印出什么?
let i=0 for(i=0;i<6;i++){setTimeout(()=>{console.log(i)},1000) }運行上面代碼,看看會打印出什么結果
let i=0 for(i=0;i<6;i++){setTimeout(()=>{console.log(i)},1000) }- JS函數的調用時機不同,得到的結果不同。
- setTimeout() 方法用于在指定的毫秒數后調用函數或計算表達式;其意思就是盡快,而不是馬上。
解釋:因為setTimeout是一個異步任務,執行到這里的操作會被瀏覽器丟到另一個任務隊列里去, 瀏覽器這時候會繼續執行for循環。每一次for循環的時候,setTimeout都執行一次,但是里面的函數沒有被執行,而是被放到了任務隊列里面,等待執行,for循環了6次,就放了6次,當主線程執行完成后,才進入任務隊列里面執行。這時候因為for循環i=6了,所以輸出的全部都是6。
如何理解異步呢?
異步代碼不等待結果,直接進行下面的代碼,所以定時器只是開啟了,而沒有立即執行里面的代碼,等到當前運行壞境的代碼執行完之后再回來執行定時器里面的代碼。總結:異步就是不等待結果的代碼。
解釋二:如案例中所示,setTimeout的調用時間為“0”(盡快調用),只有當主代碼執行完一遍后才會執行setTimeout(定時器),但這時i已經為6,所以打印出數值6.
又因為條件:i<6,共執行了6次(當i等于6時跳出循環),所有結果為一共打印出6次6。
思考:那么怎么正確顯示?(如何打印出0、1、2、3、4、5)
方法一:let關鍵字
原理:每次進入進入循環時,JS會把當前的復制一份路i在循環空間里(i=0,i=1...) 不會跟隨新的i跟變化
JS變態之處:把let聲明寫入for循環中,則會正常打印出 0、1、2、3、4、5 (服了JS,迎合新人)for(let i = 0; i<6; i++){setTimeout(()=>{console.log(i)},0) }解釋:因為let變量的作用域只能在當前函數中,所以每次for循環生成的都是一個新的i,setTimeout里輸出的i就是這個新的i,這個i是不會變化的,所以輸出的就是正常的。
迦南:var、let、consts在JavaScript變量/常量的定義?zhuanlan.zhihu.com除了使用 for let 配合,還有什么其他方法可以打印出 0、1、2、3、4、5?
方法二:
for(i=0;i<6;i++){let j = isetTimeout(()=>{console.log(j)},1000) }方法三:閉包
for(var i=0;i<6;i++){!function(i){ //這是里面的i //在匿名函數前加上運算符‘ !’,不生成新的全局變量(防止污染全局)setTimeout(()=>{console.log(i)},1000) //這是里面的i}(i) //這是外面的i //在匿名函數后加個()立即執行,并把i當作參數value傳入匿名函數循環執行,參數i和匿名函數組成了閉包 }原理:
- 聲明匿名函數 function(value){} 包裹 setTimeout()
- 然后再匿名函數前加上運算符‘ !’,防止生成新的全局變量(避免污染全局)
- 在匿名函數后加個()立即調用,并把 i 當作參數 value 傳入匿名函數進行調用
注意:參數i和匿名函數會組成了閉包
通過閉包,將i的變量駐留在內存中,當輸出j時,引用的是外部函數A的變量值i,i的值是根據循環來的,執行setTimeout時已經確定了里面的的輸出了。
方法四:利用 setTimeout 的第三個參數,將i傳進去
let i for(i = 0; i<6; i++){setTimeout((value)=>{console.log(value)},0,i) //setTimeout 第三個參數,聲明后這個參數可以將自身傳給第一個參數 function(value), }原理:
使用setTimeout 的第三個參數--這個參數可以將自身傳給第一個參數也就是匿名函數function(value)中,作為所需要的參數value,value可默認不寫
而 i 共傳入6次(0,1,2,3,4,5),通過匿名函數即可打印出
通常不寫第三個三處,如果默認不寫第三個參數,則不會傳入函數
由于每次傳入的參數是從for循環里面取到的值,所以會依次輸出0~5
簡單一句換:setTimeout的第三個參數作用,它就是當作setTimeout第一個函數的參數
方法五:const關鍵字
let i for(i = 0; i<6; i++){const x = isetTimeout(()=>{console.log(x)}) }拓展例1:
function sum(x,y,z){console.log(x+y+z); } setTimeout(sum,1000,1,2,3);拓展例2:
var i=0; setTimeout(function(){console.log('第二次'+i) },3000,setTimeout(function(){console.log('第一次'+i);i++; },1000));最后依次輸出為 第一次0 第二次1可以看到第三個參數還可以是先執行,然后再執行函數
不過還要注意一點就是:
這種傳參方式在IE9及更低的版本下是不起作用的
setTimeout的意思
setTimeout(fn(),1000) f2()1000ms后盡快執行fn(),不代表馬上執行,如f2()中寫了10000行代碼,需要花10秒執行完,那么,fn()會在10秒之后執行。
總結
以上是生活随笔為你收集整理的js for循环_JS 函数的执行时机(深入理解6个6)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: python企业微信回调_回调模式
- 下一篇: gradle idea java ssm