摘要:問題在說閉包,一定會牽涉到作用域。這也是閉包的屬性的,能夠記錄下內部函數引用外部的值。因為都是全局變量,所以循環也就是不斷值覆蓋,閉包并不會記錄在循環時的值,只會記錄閉包變量。閉包時記錄的除了閉包變量還有塊級作用域變量最后來看看這個輸出什么
js 是非常靈活的語言,寫起來真是*
不過現在有了typescript,寫起來舒服多了。
問題在說js閉包,一定會牽涉到作用域。而一般在區別 var 跟 let 時就會舉 for 循環的例子,但是這里只說 作用域,而不說閉包,那么其實還是看不懂,至于覺得很無厘頭。
在阮一峰的 let 和 const 命令一節,舉了這么一個例子。
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, 變成塊級作用域let后就正常輸出了。
動手不知道到底怎么回事,只好調試去看變量到底是什么樣?在兩個例子中都稍微增加了點東西
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); }; }
這里,循環里面有3個變量,內部函數中引用兩個。然后我們循環三次后,看看a[0], a[1]
我們發現a[0], a[1]首先是個函數對象,在scopes 中有 Closure 這個東西,這就是閉包了。
這里閉包中只有 i跟c,并沒有b, 因為b沒有在內部函數中被使用,因此沒有被scopes 記錄下來。
而且請注意,i跟c的值都是當前變量i的值。 這也是閉包的屬性的,能夠記錄下內部函數引用外部的值。因為 i, c, b 都是全局變量,所以循環也就是不斷值覆蓋,閉包并不會記錄在循環時的值,只會記錄 閉包變量。
注: 我這里是循環了3次,所以 閉包變量都是3,如果循環完了則是另外的值,你能正確說出它們的值么?
接著我們來看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三個變量,內部函數中引用兩個。然后我們循環三次后,看看a[0], a[1]
在上圖,我們可以看到scopes 增加了個新東西 Block, 這是函數記錄了 塊作用域。
看著這個圖,我們就可以這么理解: let聲明的變量i 不是全局變量,每次循環都是作用域關閉然后重新再重建,但是在內部函數又引用了 這個塊級作用域變量, 所以內部函數會記錄這個值。
而變量c 雖然也是 let聲明,為什么不是被記錄到 Block 呢,這是因為 變量c 雖然是let聲明,但是是在for循環外面, 對于這個文件來說,變量c就是全局變量,所以被記錄到 closure 中
over看完以上分析,不知道有沒有加深你對let,const 的理解, let聲明的變量是塊級作用域,const聲明的是全局變量,但也要看用在哪兒。 閉包時記錄的 除了閉包變量還有塊級作用域變量
最后來看看這個輸出什么:
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]();
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/108062.html
摘要:垃圾回收內存管理實踐先通過一個來看看在中進行垃圾回收的過程是怎樣的內存泄漏識別在環境里提供了方法用來查看當前進程內存使用情況,單位為字節中保存的進程占用的內存部分,包括代碼本身棧堆。 showImg(https://segmentfault.com/img/remote/1460000019894672?w=640&h=426);作者 | 五月君Node.js 技術棧 | https:...
摘要:模塊化是隨著前端技術的發展,前端代碼爆炸式增長后,工程化所采取的必然措施。目前模塊化的思想分為和。特別指出,事件不等同于異步,回調也不等同于異步。將會討論安全的類型檢測惰性載入函數凍結對象定時器等話題。 Vue.js 前后端同構方案之準備篇——代碼優化 目前 Vue.js 的火爆不亞于當初的 React,本人對寫代碼有潔癖,代碼也是藝術。此篇是準備篇,工欲善其事,必先利其器。我們先在代...
摘要:作用域分類作用域共有兩種主要的工作模型。換句話說,作用域鏈是基于調用棧的,而不是代碼中的作用域嵌套。詞法作用域詞法作用域中,又可分為全局作用域,函數作用域和塊級作用域。 一篇鞏固基礎的文章,也可能是一系列的文章,梳理知識的遺漏點,同時也探究很多理所當然的事情背后的原理。 為什么探究基礎?因為你不去面試你就不知道基礎有多重要,或者是說當你的工作經歷沒有亮點的時候,基礎就是檢驗你好壞的一項...
閱讀 2426·2023-04-26 00:46
閱讀 585·2023-04-25 21:36
閱讀 732·2021-11-24 10:19
閱讀 2275·2021-11-23 09:51
閱讀 1021·2021-10-21 09:39
閱讀 834·2021-09-22 10:02
閱讀 1672·2021-09-03 10:29
閱讀 2691·2019-08-30 15:53