浅谈对JavaScript闭包的理解
首先我們先來看一段代碼
從上面的代碼可以看出js都有一個特性特性,局部方法可以訪問外部父類方法的屬性,也就是說,子類或子方法可以訪問父類的資源。
我們再來看一段代碼
為什么我們打印出來的是undefined?因為子方法的變量作用域僅僅是子方法的范圍,外部是無法獲取到的。那么js中是如何獲取字方法里面的值呢?我們來看下面的代碼
在外部無法獲取到funOne內(nèi)部的局部變量,但是funOne內(nèi)部的局部方法funTwo卻可以獲取到,因此 返回一個funTwo的引用,這樣在外部通過這個funTwo就可以獲取到funOne的內(nèi)部變量。而這個方法內(nèi)的局部方法funTwo就叫做閉包。簡單的總結(jié)下有權(quán)訪問另一個函數(shù)作用域內(nèi)變量的函數(shù)都是閉包。
為什么要用閉包
我們知道,js的每個函數(shù)都是一個個小黑屋,它可以獲取外界信息,但是外界卻無法直接看到里面的內(nèi)容。將變量 myname放進小黑屋里,除了funOne函數(shù)之外,沒有其他辦法能接觸到變量myname,而且在函數(shù)funOne外定義同名的變量myname 也是互不影響的,這就是所謂的增強“封裝性”。
閉包的用途
閉包可以用在許多地方。它的最大用處有兩個,一個是前面說到的可以讀取函數(shù)內(nèi)部的變量,另一個就是讓這些變量的值始終保持在內(nèi)存中,不會在funOne調(diào)用后被自動清除。
為什么會這樣呢?原因就在于funOne是funTwo的父函數(shù),而funTwo被賦給了一個全局變量,這導(dǎo)致funTwo始終在內(nèi)存中,而funTwo的存在依賴于funOne,因此funOne也始終在內(nèi)存中,不會在調(diào)用結(jié)束后,被回收。好比一個餐廳,盤子總是有限的,所以服務(wù)員會去巡臺回收空盤子,但還裝著菜的盤子他怎么敢收?
注意!!
(1) 由于閉包會使得函數(shù)中的變量都被保存在內(nèi)存中,內(nèi)存消耗很大,所以不能濫用閉包,否則會造成網(wǎng)頁的性能問題,在IE中可能導(dǎo)致內(nèi)存泄露。解決方法是,在退出函數(shù)之前,將不使用的局部變量全部刪除。
(2) 閉包會在父函數(shù)外部,改變父函數(shù)內(nèi)部變量的值。所以,,不要隨便改變父函數(shù)內(nèi)部變量的值。
常見缺陷
函數(shù)帶()才是執(zhí)行函數(shù)單純的一句 var myname =funOne; 是不會打印的,后面接一myname (); 才會執(zhí)行函數(shù)內(nèi)部的代碼。
總結(jié)
其實很多的方法都是給予閉包像redux 中的store就是用閉包和觀察者模式來完成的,閉包應(yīng)用的地方很多也很廣泛,可以和很多的東西搭配,所以我們的路還有很長,這只是一個開始(未完待續(xù)。。。)
總結(jié)
以上是生活随笔為你收集整理的浅谈对JavaScript闭包的理解的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: thinkphp5项目--个人博客(六)
- 下一篇: 解决tomcat同时部署多个Spring