摘要:修改下面代碼,使其能夠正確運(yùn)行為什么上面代碼的執(zhí)行結(jié)果是首先說明,這與異步和作用域都有關(guān)系。先來說和異步的關(guān)系,是異步操作,所謂的異步就是會(huì)在同步操作全部執(zhí)行完成之后,才開始執(zhí)行的。
// 修改下面代碼,使其能夠正確運(yùn)行 for(var i = 0; i < 6; i++) { setTimeout(function timer(){ console.log(i) }, i * 1000) }
為什么上面代碼的執(zhí)行結(jié)果是 [6,6,6,6,6,6] ?
首先說明,這與異步和作用域都有關(guān)系。
先來說和異步的關(guān)系,setTimeout是異步操作,所謂的異步就是會(huì)在同步操作全部執(zhí)行完成之后,才開始執(zhí)行的。放在上面的代碼中解釋就是,setTimeout是在每次for循環(huán)的時(shí)候都會(huì)調(diào)用的(用于將setTimeout內(nèi)部的代碼放入隊(duì)列,在同步代碼執(zhí)行完成之后,再根據(jù)定時(shí)執(zhí)行),但是setTimeout中的代碼是在for循環(huán)結(jié)束之后才開始執(zhí)行的,所以當(dāng)for循環(huán)執(zhí)行完成的時(shí)候,i變成了6,那么timer中對(duì)i的引用也變成了6。
然后是和作用域的關(guān)系,for循環(huán)中定義的變量i ,它的作用域是什么?
for(var i = 0; i<6; i++) ----> var i = 0; for(i; i<6; i++)
是 window,所以當(dāng)for循環(huán)執(zhí)行完成的時(shí)候,全局變量i的值為6,此時(shí)去執(zhí)行隊(duì)列中的timer函數(shù),但是timer中并沒有定義i,所以就會(huì)沿著作用域鏈向外層查找,就找到了window中的全局變量i,值為6。
// 第一種方法:使用立即執(zhí)行函 for(var i = 0; i < 6; i++) { (function(j){ setTimeout(function timer(){ console.log(j) }, j * 1000) })(i) } // 第二種方法:使用let關(guān)鍵字 for(let i = 0; i < 6; i++) { setTimeout(function timer(){ console.log(i) }, i * 1000) }
這兩種方法的本質(zhì)其實(shí)是一樣的,都是創(chuàng)建了一個(gè)新的變量去保存for循環(huán)中每次變化的i的值,再將其傳遞給timer,使timer每次在執(zhí)行的時(shí)候都能得到正確的值。在使用let的時(shí)候,可以看到babel將其轉(zhuǎn)譯之后的結(jié)果,使用了一個(gè)新的參數(shù)來保存每次循環(huán)時(shí)的i,所以在6次循環(huán)中,會(huì)開辟出6個(gè)內(nèi)存空間,保存著6個(gè)不同的i ,這樣的話,setTimeout中對(duì)i的引用就能得到正確的值。
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/99503.html
摘要:同步異步回調(diào)傻傻分不清楚。分割線上面主要講了同步和回調(diào)執(zhí)行順序的問題,接著我就舉一個(gè)包含同步異步回調(diào)的例子。同步優(yōu)先回調(diào)內(nèi)部有個(gè),第二個(gè)是一個(gè)回調(diào)回調(diào)墊底。異步也,輪到回調(diào)的孩子們回調(diào),出來執(zhí)行了。 同步、異步、回調(diào)?傻傻分不清楚。 大家注意了,教大家一道口訣: 同步優(yōu)先、異步靠邊、回調(diào)墊底(讀起來不順) 用公式表達(dá)就是: 同步 => 異步 => 回調(diào) 這口訣有什么用呢?用來對(duì)付面試的...
摘要:同步異步回調(diào)傻傻分不清楚。分割線上面主要講了同步和回調(diào)執(zhí)行順序的問題,接著我就舉一個(gè)包含同步異步回調(diào)的例子。同步優(yōu)先回調(diào)內(nèi)部有個(gè),第二個(gè)是一個(gè)回調(diào)回調(diào)墊底。異步也,輪到回調(diào)的孩子們回調(diào),出來執(zhí)行了。 同步、異步、回調(diào)?傻傻分不清楚。 大家注意了,教大家一道口訣: 同步優(yōu)先、異步靠邊、回調(diào)墊底(讀起來不順) 用公式表達(dá)就是: 同步 => 異步 => 回調(diào) 這口訣有什么用呢?用來對(duì)付面試的...
摘要:瀏覽器是多進(jìn)程的,而瀏覽器的內(nèi)核渲染進(jìn)程是多線程的。如果已經(jīng)將回調(diào)函數(shù)放進(jìn)任務(wù)隊(duì)列,但是主線程正在執(zhí)行一個(gè)非常耗時(shí)的任務(wù),當(dāng)這個(gè)任務(wù)執(zhí)行完畢后,主線程去任務(wù)隊(duì)列中取任務(wù),這個(gè)時(shí)候,就會(huì)出現(xiàn)連續(xù)執(zhí)行的情況,也就是說相當(dāng)于失效了。 前言 ??在刷筆試題的時(shí)候,經(jīng)常會(huì)碰到setTimeout的問題,只知道這個(gè)是設(shè)置定時(shí)器;但是考察的重點(diǎn)一般是在一個(gè)方法中包含了定時(shí)器,定時(shí)器中的打印和方法中打...
摘要:注意如果主邏輯的代碼執(zhí)行時(shí)間已經(jīng)超過了第二個(gè)參數(shù)設(shè)置的時(shí)間,那么等運(yùn)行到該回調(diào)函數(shù)時(shí),它會(huì)忽略掉這個(gè)時(shí)間,并立即執(zhí)行。如果某一個(gè)進(jìn)行大量的計(jì)算,那么它就會(huì)阻塞在當(dāng)前的回調(diào)函數(shù)中,等待該計(jì)算完成后,再執(zhí)行下一個(gè)的回調(diào)函數(shù)。 setTimeout() ? JavaScript是一個(gè)單線程的語言,也就是說它同一時(shí)間只能執(zhí)行一段代碼,接下來我們通過兩個(gè)例子說明一下單線程語言和多線程語言的...
閱讀 1966·2023-04-25 16:19
閱讀 3091·2021-11-24 09:39
閱讀 829·2021-11-16 11:44
閱讀 1688·2019-08-29 12:52
閱讀 1138·2019-08-26 13:33
閱讀 1073·2019-08-26 10:26
閱讀 2200·2019-08-23 16:42
閱讀 2567·2019-08-23 14:37