摘要:?jiǎn)栴}在說閉包,一定會(huì)牽涉到作用域。這也是閉包的屬性的,能夠記錄下內(nèi)部函數(shù)引用外部的值。因?yàn)槎际侨肿兞?,所以循環(huán)也就是不斷值覆蓋,閉包并不會(huì)記錄在循環(huán)時(shí)的值,只會(huì)記錄閉包變量。閉包時(shí)記錄的除了閉包變量還有塊級(jí)作用域變量最后來看看這個(gè)輸出什么
js 是非常靈活的語言,寫起來真是*
不過現(xiàn)在有了typescript,寫起來舒服多了。
問題在說js閉包,一定會(huì)牽涉到作用域。而一般在區(qū)別 var 跟 let 時(shí)就會(huì)舉 for 循環(huán)的例子,但是這里只說 作用域,而不說閉包,那么其實(shí)還是看不懂,至于覺得很無厘頭。
在阮一峰的 let 和 const 命令一節(jié),舉了這么一個(gè)例子。
var a = []; for (var i = 0; i < 10; i++) { a[i] = function () { console.log(i); }; } a[6](); // 10
跟
var a = []; for (let i = 0; i < 10; i++) { a[i] = function () { console.log(i); }; } a[6](); // 6
然后我就不清楚了,為什么使用var全局變量后, 就輸出10, 變成塊級(jí)作用域let后就正常輸出了。
動(dòng)手不知道到底怎么回事,只好調(diào)試去看變量到底是什么樣?在兩個(gè)例子中都稍微增加了點(diǎn)東西
var a = []; var b; var c; for (var i = 0; i < 10; i++) { b = i; c = i; a[i] = function () { console.log(i); console.log(c); }; }
這里,循環(huán)里面有3個(gè)變量,內(nèi)部函數(shù)中引用兩個(gè)。然后我們循環(huán)三次后,看看a[0], a[1]
我們發(fā)現(xiàn)a[0], a[1]首先是個(gè)函數(shù)對(duì)象,在scopes 中有 Closure 這個(gè)東西,這就是閉包了。
這里閉包中只有 i跟c,并沒有b, 因?yàn)閎沒有在內(nèi)部函數(shù)中被使用,因此沒有被scopes 記錄下來。
而且請(qǐng)注意,i跟c的值都是當(dāng)前變量i的值。 這也是閉包的屬性的,能夠記錄下內(nèi)部函數(shù)引用外部的值。因?yàn)?i, c, b 都是全局變量,所以循環(huán)也就是不斷值覆蓋,閉包并不會(huì)記錄在循環(huán)時(shí)的值,只會(huì)記錄 閉包變量。
注: 我這里是循環(huán)了3次,所以 閉包變量都是3,如果循環(huán)完了則是另外的值,你能正確說出它們的值么?
接著我們來看let 的改編
var a = []; let b; let c; for (let i = 0; i < 10; i++) { b = i; c = i; a[i] = function oo() { console.log(i); console.log(c); }; } a[6](); // 6
同樣,這里依舊i,b,c三個(gè)變量,內(nèi)部函數(shù)中引用兩個(gè)。然后我們循環(huán)三次后,看看a[0], a[1]
在上圖,我們可以看到scopes 增加了個(gè)新東西 Block, 這是函數(shù)記錄了 塊作用域。
看著這個(gè)圖,我們就可以這么理解: let聲明的變量i 不是全局變量,每次循環(huán)都是作用域關(guān)閉然后重新再重建,但是在內(nèi)部函數(shù)又引用了 這個(gè)塊級(jí)作用域變量, 所以內(nèi)部函數(shù)會(huì)記錄這個(gè)值。
而變量c 雖然也是 let聲明,為什么不是被記錄到 Block 呢,這是因?yàn)?變量c 雖然是let聲明,但是是在for循環(huán)外面, 對(duì)于這個(gè)文件來說,變量c就是全局變量,所以被記錄到 closure 中
over看完以上分析,不知道有沒有加深你對(duì)let,const 的理解, let聲明的變量是塊級(jí)作用域,const聲明的是全局變量,但也要看用在哪兒。 閉包時(shí)記錄的 除了閉包變量還有塊級(jí)作用域變量
最后來看看這個(gè)輸出什么:
var a = []; let b; let c; for (let i = 0; i < 10; i++) { b = i; c = i; var n = i; let m = i; a[i] = function oo() { console.log(i); console.log(c); console.log(n); console.log(m); }; } a[6]();
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/108062.html
摘要:常見問題說到閉包相關(guān)的問題,最典型的就是變量和指向這兩類問題。如果有錯(cuò)誤或不嚴(yán)謹(jǐn)?shù)牡胤?,歡迎批評(píng)指正,如果喜歡,歡迎點(diǎn)贊。 引言 閉包這個(gè)詞對(duì)很多前端開發(fā)人員來說既熟悉又陌生,熟悉是因?yàn)楹芏嗳硕加眠^閉包,但是用的時(shí)候不知道閉包,陌生是因?yàn)椴⒉焕斫忾]包,接下來這篇文章將會(huì)從多方面介紹閉包 定義 閉包是怎么定義的呢?當(dāng)函數(shù)可以記住并訪問所在的詞法作用域時(shí),就產(chǎn)生了閉包,即使函數(shù)在當(dāng)前詞法作...
摘要:垃圾回收內(nèi)存管理實(shí)踐先通過一個(gè)來看看在中進(jìn)行垃圾回收的過程是怎樣的內(nèi)存泄漏識(shí)別在環(huán)境里提供了方法用來查看當(dāng)前進(jìn)程內(nèi)存使用情況,單位為字節(jié)中保存的進(jìn)程占用的內(nèi)存部分,包括代碼本身?xiàng)6选? showImg(https://segmentfault.com/img/remote/1460000019894672?w=640&h=426);作者 | 五月君Node.js 技術(shù)棧 | https:...
摘要:模塊化是隨著前端技術(shù)的發(fā)展,前端代碼爆炸式增長(zhǎng)后,工程化所采取的必然措施。目前模塊化的思想分為和。特別指出,事件不等同于異步,回調(diào)也不等同于異步。將會(huì)討論安全的類型檢測(cè)惰性載入函數(shù)凍結(jié)對(duì)象定時(shí)器等話題。 Vue.js 前后端同構(gòu)方案之準(zhǔn)備篇——代碼優(yōu)化 目前 Vue.js 的火爆不亞于當(dāng)初的 React,本人對(duì)寫代碼有潔癖,代碼也是藝術(shù)。此篇是準(zhǔn)備篇,工欲善其事,必先利其器。我們先在代...
摘要:作用域分類作用域共有兩種主要的工作模型。換句話說,作用域鏈?zhǔn)腔谡{(diào)用棧的,而不是代碼中的作用域嵌套。詞法作用域詞法作用域中,又可分為全局作用域,函數(shù)作用域和塊級(jí)作用域。 一篇鞏固基礎(chǔ)的文章,也可能是一系列的文章,梳理知識(shí)的遺漏點(diǎn),同時(shí)也探究很多理所當(dāng)然的事情背后的原理。 為什么探究基礎(chǔ)?因?yàn)槟悴蝗ッ嬖嚹憔筒恢阑A(chǔ)有多重要,或者是說當(dāng)你的工作經(jīng)歷沒有亮點(diǎn)的時(shí)候,基礎(chǔ)就是檢驗(yàn)?zāi)愫脡牡囊豁?xiàng)...
閱讀 2432·2023-04-26 00:46
閱讀 593·2023-04-25 21:36
閱讀 737·2021-11-24 10:19
閱讀 2282·2021-11-23 09:51
閱讀 1028·2021-10-21 09:39
閱讀 841·2021-09-22 10:02
閱讀 1677·2021-09-03 10:29
閱讀 2707·2019-08-30 15:53