摘要:昨天總結(jié)了一些作用域的知識(shí)前端工程師手冊(cè)之作用域,但是發(fā)表完發(fā)現(xiàn)忘記了一些東西,今天拾個(gè)遺。循環(huán)完畢之后,,且此時(shí)生成了個(gè)匿名函數(shù),由于這個(gè)匿名函數(shù)處在同一個(gè)詞法作用域中,所以他們引用同一個(gè),所以當(dāng)他們執(zhí)行時(shí),自然而然就會(huì)打出。
昨天總結(jié)了一些作用域的知識(shí)【前端工程師手冊(cè)】JavaScript之作用域,但是發(fā)表完發(fā)現(xiàn)忘記了一些東西,今天拾個(gè)遺。
昨天說(shuō)到了JavaScript中沒有塊級(jí)作用域,其實(shí)在es6中是有的。
先舉個(gè)栗子:
var foo = true; if (foo) { let bar = foo * 2; bar = something( bar ); console.log(bar); } console.log( bar ); // ReferenceError
這個(gè)是let最直觀的作用,在一對(duì)大括號(hào)中創(chuàng)建了塊級(jí)作用域,bar會(huì)在大括號(hào)中的代碼執(zhí)行完畢后銷毀。
再舉個(gè)栗子:
for(var i = 1;i <= 5;i++) { setTimeout(function() { console.log(i) }, i*1000) } // 每隔一秒打印一個(gè)6,共打印5次
如果說(shuō)這段代碼的初衷是間隔1秒打印出1、2、3、4、5的話,結(jié)果是令人大跌眼鏡的,真正的結(jié)果是每隔1秒打印一次6,打印5次.
為什么會(huì)這樣子?首先是因?yàn)殚]包的原因,閉包后面再說(shuō),現(xiàn)在先理解為閉包是一個(gè)函數(shù),一個(gè)能夠訪問(wèn)并未在它自己內(nèi)部定義的變量的函數(shù)。
OK,接下來(lái)說(shuō)深層次原因。for循環(huán)完畢之后,i=6,且此時(shí)生成了5個(gè)匿名函數(shù) function(){ console.log(i) },由于這5個(gè)匿名函數(shù)處在同一個(gè)詞法作用域中,所以他們引用同一個(gè)i,所以當(dāng)他們執(zhí)行時(shí),自然而然就會(huì)打出6。
如何解決?
for(let i = 1;i <= 5;i++) { setTimeout(function() { console.log(i) }, i*1000) } // 間隔一秒分別打印出1、2、3、4、5
把var換成let聲明就可以了。
《你不知道的JavaScript-上卷》中解釋道:
for 循環(huán)頭部的 let 不僅將 i 綁定到了 for 循環(huán)的塊中,事實(shí)上它將其重新綁定到了循環(huán)的每一個(gè)迭代中,確保使用上一個(gè)循環(huán)迭代結(jié)束時(shí)的值重新進(jìn)行賦值。
說(shuō)白了就是再每次迭代內(nèi)部,都會(huì)對(duì) i 進(jìn)行隱形的重新賦值,且使用的是上一個(gè)迭代結(jié)束時(shí)的值來(lái)對(duì) i 進(jìn)行重新賦值。
差不多就是這樣的:
for(let i = 1;i <= 5;i++) { let i = 上次迭代結(jié)束的i setTimeout(function() { console.log(i) }, i*1000) }
所以5個(gè)匿名函數(shù)引用的并不是同一個(gè)i,自然就會(huì)順利的間隔一秒分別打印出1、2、3、4、5了
參考資料:
你不知道的JavaScript-上卷
let-MDN
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://m.specialneedsforspecialkids.com/yun/94899.html
摘要:之前總結(jié)了的一些常見綁定情況前端工程師手冊(cè)之的筆記,但是還有一些沒有說(shuō)到,今天繼續(xù)學(xué)習(xí)一下。參考資料箭頭函數(shù)你不知道的上卷 之前總結(jié)了this的一些常見綁定情況(【前端工程師手冊(cè)】JavaScript之this的筆記),但是還有一些沒有說(shuō)到,今天繼續(xù)學(xué)習(xí)一下。 es6箭頭函數(shù) 先說(shuō)結(jié)論:箭頭函數(shù)沒有自己的this,它是根據(jù)外層(函數(shù)或者全局,后面會(huì)說(shuō)到箭頭函數(shù)作為某個(gè)對(duì)象的方法時(shí)的情況...
摘要:難怪超過(guò)三分之一的開發(fā)人員工作需要一些知識(shí)。但是隨著行業(yè)的飽和,初中級(jí)前端就業(yè)形勢(shì)不容樂(lè)觀。整個(gè)系列的文章大概有篇左右,從我是如何成為一個(gè)前端工程師,到各種前端框架的知識(shí)。 為什么 call 比 apply 快? 這是一個(gè)非常有意思的問(wèn)題。 作者會(huì)在參數(shù)為3個(gè)(包含3)以內(nèi)時(shí),優(yōu)先使用 call 方法進(jìn)行事件的處理。而當(dāng)參數(shù)過(guò)多(多余3個(gè))時(shí),才考慮使用 apply 方法。 這個(gè)的原因...
摘要:難怪超過(guò)三分之一的開發(fā)人員工作需要一些知識(shí)。但是隨著行業(yè)的飽和,初中級(jí)前端就業(yè)形勢(shì)不容樂(lè)觀。整個(gè)系列的文章大概有篇左右,從我是如何成為一個(gè)前端工程師,到各種前端框架的知識(shí)。 為什么 call 比 apply 快? 這是一個(gè)非常有意思的問(wèn)題。 作者會(huì)在參數(shù)為3個(gè)(包含3)以內(nèi)時(shí),優(yōu)先使用 call 方法進(jìn)行事件的處理。而當(dāng)參數(shù)過(guò)多(多余3個(gè))時(shí),才考慮使用 apply 方法。 這個(gè)的原因...
摘要:由于網(wǎng)景公司希望能在靜態(tài)頁(yè)面上添加一些動(dòng)態(tài)效果,于是叫這哥們?cè)趦芍苤畠?nèi)設(shè)計(jì)出了語(yǔ)言。所以簡(jiǎn)單說(shuō)來(lái)就是,是一種語(yǔ)言標(biāo)準(zhǔn),而是網(wǎng)景公司對(duì)標(biāo)準(zhǔn)的一種實(shí)現(xiàn)。 JavaScript基礎(chǔ)拾遺 study notes by Tingting 為啥說(shuō)JavaScript的基礎(chǔ) 在平時(shí)開發(fā)時(shí),我們更多的是在寫PHP的邏輯層,但是在寫后臺(tái)時(shí)多多少少會(huì)寫一寫JavaScript的代碼,有時(shí)候我們就會(huì)遇到對(duì)j...
摘要:函數(shù)作用域和塊作用域前面講了是詞法作用域,那么什么時(shí)候會(huì)創(chuàng)建作用域呢主要是基于函數(shù)級(jí)別的作用域,也就是每一個(gè)函數(shù)都會(huì)創(chuàng)建一個(gè)作用域。函數(shù)會(huì)被當(dāng)作函數(shù)表達(dá)式而不是一個(gè)標(biāo)準(zhǔn)的函數(shù)聲明來(lái)處理。 什么是作用域 來(lái)一段《你不知道的JavaScript-上卷》中的原話: 幾乎所有編程語(yǔ)言最基本的功能之一,就是能夠儲(chǔ)存變量當(dāng)中的值,并且能在之后對(duì)這個(gè) 值進(jìn)行訪問(wèn)或修改,這些變量住在哪里?換句話說(shuō),它...
閱讀 1419·2021-10-08 10:04
閱讀 742·2021-09-07 09:58
閱讀 2921·2019-08-30 15:55
閱讀 2473·2019-08-29 17:21
閱讀 2174·2019-08-28 18:04
閱讀 3083·2019-08-28 17:57
閱讀 728·2019-08-26 11:46
閱讀 2260·2019-08-23 17:20