摘要:在中,閉包其實隨處可見。但真要說起什么是閉包的話,很多人可能一時半會不知道怎么解釋。這篇博文主要寫一些閉包的特性已經相關的應用。
在JavaScript中,閉包其實隨處可見。但真要說起什么是閉包的話,很多人可能一時半會不知道怎么解釋。這篇博文主要寫一些閉包的特性已經相關的應用。定義
參考資料:阮一峰——JavaScript運行機制詳解
閉包是指在函數聲明時的作用域以外的地方被調用的函數,在函數聲明時的作用域以外的地方調用函數,需要通過將該函數作為返回值或者作為參數被傳遞
特性光看定義的話可能會比較懵逼(╯‵□′)╯︵┻━┻ 下面來看一下閉包到底都有哪些特性:
函數在自己定義的詞法作用域以外的地方執行
函數嵌套
訪問所在的詞法作用域
循環閉包 定義在循環中包含了函數定義則稱為循環閉包
實例1講了這么多,下面來看一段例子:
for(var i = 1; i < 6; i++){ setTimeout(function(){ console.log(i); },50); } //輸出結果為: 6 6 6 6 6
好吧,如果你是新手的話,看到這里你是震驚的,因為作為一個萌新,當初我對這串代碼的想法是這樣的:
setTimeout函數在for循環中執行六次,每隔50ms輸出一個數字,則會分別輸出1、2、3、4、5
后來我發現,用關鍵字var聲明的變量會存在變量提升的情況,循環結束以后,變量i不會被JavaScript引擎的垃圾回收機制回收,而是成為全局變量。
所以我的的初步解釋為:
由關鍵字var聲明的變量存在變量提升的情況,循環結束以后變量i變為全局變量
for循環結束的比50ms要早,所以setTimeout函數讀取不到迭代的變量i,而是循環結束后的變量i
實例2然而上面只是我一開始錯誤的認識,直到我看到下面的代碼:
for(var i=1;i<6;i++){ setTimeout(function(){ console.log(i); },0); } //輸出結果為: 6 6 6 6 6
因為這里setTimeout的時間參數是0,如果照著上面的思路來的話,這里的輸出應該是 1 2 3 4 5
JavaScript調用機制在講述解決方法之前我們先來了解一下JavaScript的調用機制
對JavaScript比較熟悉的人應該了解,JavaScript是一種單線程的語言。而我們在編寫代碼的時候,往往不止同步的代碼,還有異步執行的代碼,JavaScript這里把它分成兩種模式,一種叫做同步任務,另一種則叫做異步任務。在執行代碼的時候,同步任務被分配在主線程中執行,形成一個調用棧;而異步任務則交給瀏覽器的其他線程去執行。當異步任務執行完畢以后,則將對應的異步任務放入任務隊列中。當調用棧中的任務都執行完畢以后,再讀取任務隊列,取消對應任務的等待狀態,然后進入調用棧,開始執行。解決方法
方法1:綁定作用域,將關鍵字var改為let,具體代碼為:
for(let i=1;i<6;i++){ setTimeout(function(){ console.log(i) },50) }
方法2:運用IIFE(立即執行函數),具體代碼為:
for(var i=1;i<6;i++){ (function(j){ setTimeout(function(){ console.log(j) },50) })(i); }
在迭代內部使用IIFE會為每個迭代生成一個新的作用域,使得延遲函數的回調可以將新的作用域封閉在每個迭代內部,每個迭代都含有一個具有正確值的變量供我們訪問
總結閉包在JavaScript里隨處可見,我們在使用閉包的時候,需要謹慎的在循環內部添加閉包。個人覺得最好的解決方案就是使用關鍵字let,可讀性強而且另代碼整潔,希望ES6能夠全面普及。
掃描下方的二維碼或搜索「tony老師的前端補習班」關注我的微信公眾號,那么就可以第一時間收到我的最新文章。
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/85016.html
摘要:大名鼎鼎的閉包面試必問。閉包的作用是什么。看到閉包在哪了嗎閉包到底是什么五年前,我也被這個問題困擾,于是去搜了并總結下來。關于閉包的謠言閉包會造成內存泄露錯。閉包里面的變量明明就是我們需要的變量,憑什么說是內存泄露這個謠言是如何來的因為。 本文為饑人谷講師方方原創文章,首發于 前端學習指南。 大名鼎鼎的閉包!面試必問。請用自己的話簡述 什么是「閉包」。 「閉包」的作用是什么。 首先...
摘要:完美的閉包,對,閉包就這么簡單。這僅僅是閉包的一部分,閉包利用函數作用域達到了訪問外層變量的目的。此時一個完整的閉包實現了,的垃圾回收機制由于閉包的存在無法銷毀變量。 1.閉包是指有權訪問另一個函數作用域中的變量的函數。 上面這段話來自 javascript 高級程序設計 第三版 P178 。作者說閉包是一個函數,它有訪問另一個函數作用域中的變量的能力。 2.函數訪問它被創建時所處的...
摘要:到底什么是閉包這個問題在面試是時候經常都會被問,很多小白一聽就懵逼了,不知道如何回答好。上面這么說閉包是一種特殊的對象。閉包的注意事項通常,函數的作用域及其所有變量都會在函數執行結束后被銷毀。從而使用閉包模塊化代碼,減少全局變量的污染。 閉包,有人說它是一種設計理念,有人說所有的函數都是閉包。到底什么是閉包?這個問題在面試是時候經常都會被問,很多小白一聽就懵逼了,不知道如何回答好。這個...
閱讀 1936·2021-11-15 17:58
閱讀 2131·2021-10-19 11:45
閱讀 3482·2021-09-02 15:40
閱讀 2595·2021-07-25 10:50
閱讀 3745·2019-08-30 15:56
閱讀 3146·2019-08-30 12:44
閱讀 1028·2019-08-26 13:38
閱讀 1869·2019-08-23 18:29