第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

為了賬號(hào)安全,請(qǐng)及時(shí)綁定郵箱和手機(jī)立即綁定
已解決430363個(gè)問(wèn)題,去搜搜看,總會(huì)有你想問(wèn)的

setTimeout閉包疑問(wèn)

setTimeout閉包疑問(wèn)

眼眸繁星 2019-04-13 08:36:42
代碼如下:jsvardiv=$('#appendHere');$('#clickMe').on('click',function(){varthat=this;div.append(checkForWindow(this));setTimeout(function(){div.append(checkForWindow(this));div.append('thatisthe'+that.tagName+'');},300);});functioncheckForWindow(elm){if(elminstanceofWindow){return'thisistheWindow';}elseif(elm.tagName){return('thisisthe'+elm.tagName+'');}else{return('thisis'+elm+'');}}輸出結(jié)果:(另見:http://jsfiddle.net/dposin/okjr81ev/light/)thisistheBUTTONthisistheWindowthatistheBUTTON問(wèn)題來(lái)了,setTimeout中的checkForWindow(this)為什么沒有形成閉包,而that又形成閉包了呢?這樣寫就能形成閉包?本來(lái)我以為是要這樣寫的:jsfor(vari=0;i
查看完整描述

2 回答

?
www說(shuō)

TA貢獻(xiàn)1775條經(jīng)驗(yàn) 獲得超8個(gè)贊

其實(shí)JS中的所有function均為(lexical)closure,所以直接理解了函數(shù)的定義與執(zhí)行過(guò)程自然就理解closure的特點(diǎn)了。
function在定義的時(shí)候(就是生成FunctionObject的)會(huì)將當(dāng)前EC的ScopeChain作為自身的[[Scope]]的屬性值,其中that變量位于當(dāng)前EC的AO中,因此自然也在settimeout延遲執(zhí)行函數(shù)的[[Scope]]屬性中。
然后在settimeout的延遲執(zhí)行函數(shù)執(zhí)行時(shí)會(huì)先構(gòu)建自己的EC,新EC中的ScopeChain=AO+[[Scope]],然后在延遲函數(shù)中訪問(wèn)that時(shí)則在ScopeChain解析這個(gè)引用,那自然能找到之前設(shè)置的值。
而this是關(guān)鍵字,跟變量是不同的,因此不會(huì)在ScopeChain上解析。在EC中有一個(gè)ContextObject的屬性,我們?cè)L問(wèn)this其實(shí)就是訪問(wèn)EC的ContextObject,這個(gè)屬性是根據(jù)函數(shù)的調(diào)用方式來(lái)決定的(暫且這樣理解吧,其實(shí)底層有一套比較難理解的規(guī)范的)
functioncallMeBaby(){console.log(this)}
callMeBaby()//顯示[objectWindow],this指向window
host={callMeBaby:callMeBaby}
host.callMeBaby()//顯示[objectObject],this指向host
上面可以理解為this就是指向函數(shù)調(diào)用時(shí)的所屬對(duì)象,如果沒有所屬對(duì)象則指向全局對(duì)象(window)。下面示例就只能理解底層原理后才能理解透了,先留個(gè)坑吧
(1,host.callMeBaby)()//顯示[objectWindow],this指向window
                            
查看完整回答
反對(duì) 回復(fù) 2019-04-13
?
開滿天機(jī)

TA貢獻(xiàn)1786條經(jīng)驗(yàn) 獲得超13個(gè)贊

說(shuō)說(shuō)個(gè)人的理解,樓主可能對(duì)閉包的理解有些問(wèn)題,閉包是指返回的函數(shù)能夠保留對(duì)其父函數(shù)中變量的引用
而樓主說(shuō)的問(wèn)題,其實(shí)是this的指向問(wèn)題,和閉包沒有什么關(guān)系,現(xiàn)在說(shuō)說(shuō)我對(duì)上面現(xiàn)象的理解:
div.append(checkForWindow(this));這個(gè)里面的this是調(diào)用觸發(fā)當(dāng)前函數(shù)的element,也就是BUTTON;
然后varthat=this;這里將element賦值給that,這里的that就是個(gè)普通的變量名,不是關(guān)鍵字,沒有任何特殊意義;
接下來(lái)到setTimeout語(yǔ)句,其中傳入的為一個(gè)匿名函數(shù),這個(gè)不是什么閉包就是個(gè)函數(shù),然后這個(gè)定時(shí)器在300ms之后被調(diào)用了,里面又調(diào)用了div.append(checkForWindow(this));,這個(gè)時(shí)候,this的指向已經(jīng)變了,根據(jù)this的定義,this是指向調(diào)用當(dāng)前函數(shù)的對(duì)象,而對(duì)于這種匿名函數(shù)的調(diào)用,這時(shí)this指向的就是頂級(jí)的window;因此打印出來(lái)就是Window;
最后的that,這個(gè)和閉包也沒有什么關(guān)系,這個(gè)根據(jù)作用域的知識(shí),可以知道在匿名函數(shù)中沒有這個(gè)變量,因此去更加高一級(jí)去尋找這個(gè)變量,也就是指向BUTTON的this;
最后說(shuō)說(shuō)樓主的這個(gè)函數(shù)
for(vari=0;i<10;i++){
setTimeout((function(i){
console.log(i);
})(i),0);
}
這個(gè)其中的
(function(i){
console.log(i);
})(i)
這個(gè)叫立即執(zhí)行函數(shù),其中的i會(huì)被存儲(chǔ)起來(lái),是一個(gè)閉包,因此會(huì)打印出0到9的數(shù)字,但是這個(gè)寫法對(duì)于定時(shí)器來(lái)說(shuō)也是有問(wèn)題的,你會(huì)發(fā)現(xiàn)不論你的時(shí)間間隔設(shè)置多長(zhǎng),都是瞬間完成,因?yàn)檫@個(gè)函數(shù)直接執(zhí)行了,其實(shí)賦值給定時(shí)器是一個(gè)undefined,也就是說(shuō),setTimeout其實(shí)沒有執(zhí)行函數(shù),你看到的打印數(shù)字是在你定義setTimeout的時(shí)候打印出來(lái)的
正確的寫法是
for(vari=0;i<10;i++){
setTimeout((function(i){
returnfunction(){
console.log(i);
}
})(i),xxtime);
}
這樣寫會(huì)在xxtimems之后連續(xù)執(zhí)行10個(gè)定時(shí)器
                            
查看完整回答
反對(duì) 回復(fù) 2019-04-13
  • 2 回答
  • 0 關(guān)注
  • 402 瀏覽
慕課專欄
更多

添加回答

舉報(bào)

0/150
提交
取消
微信客服

購(gòu)課補(bǔ)貼
聯(lián)系客服咨詢優(yōu)惠詳情

幫助反饋 APP下載

慕課網(wǎng)APP
您的移動(dòng)學(xué)習(xí)伙伴

公眾號(hào)

掃描二維碼
關(guān)注慕課網(wǎng)微信公眾號(hào)