javascript
闭包 | 浅谈JavaScript闭包问题
1.前言
閉包這個東西在JavaScript中是一個很強大的東西,但是在初學的階段總是被其概念繞暈,搞不清楚到底什么是閉包,感覺很高深。作者在剛學的時候也有一點懵圈,多看幾次就會有自己的理解。任何東西都沒有唯一的標準,只要適合自己,自己能夠理解的就是正確的。由于作者水平有限,將自己的一些見解拿出來,希望大家能夠提出寶貴的意見。
2.作用域
在正式講閉包之前,我們來簡單的說一說作用域這個東西。這個很有助于大家理解后面的閉包。
什么是域?簡單的說就是一個被圈起來的地方,也就是變量能夠訪問的一個范圍。
眾所周知,變量的作用域分為全局變量和局部變量。定義在函數外部的稱為全局變量,在函數內部的稱為局部變量。這里順帶提一下,變量提升這個玩意兒,也就是和“先聲明后使用差不多的道理”,后面我將會舉一個例子來說明。
舉個例子,全局變量和局部變量:
| 1 2 3 4 5 6 7 8 9 10 11 12 復制代碼 | var a='wang'; function fun(){var b='huagang';console.log('這是在函數內部的輸出');console.log(a);console.log(b); } fun();//調用函數console.log("這是在函數外部的輸出"); console.log(a); console.log(b); 復制代碼 |
運行結果:
最后一個輸出b的時候拋出了一個未定義異常,由此可見,全局變量(a)在函數內部和外部都是能訪問的,但是局部變量不是這樣的,在函數作用域外是不能訪問到函數內部的變量(b)的。這里順帶講一下【變量提升】吧,簡單的舉一個例子。
| 1 2 3 4 復制代碼 | var a; console.log(a); a='wang'; console.log(a) 復制代碼 |
根據輸出情況可以看出,第一次輸出a并沒有報異常,而是undefined。第二次便能輸出a的值。這就是變量提升的特點,在變量還沒賦值前就拿來使用了。
3.嵌套函數的作用域
嵌套函數,顧名思義就是在函數的內部再寫一個或多個函數。下面舉一個例子來講解一下嵌套函數的作用域。
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 復制代碼 | function funA(c){var a='wang';function funB(){var b='gang';console.log("在函數B中的輸出:")console.log(a);console.log(c);console.log(b);}funB();console.log("在函數A中的輸出:")console.log(a);console.log(c);console.log(b); } funA('hua');//調用函數A并傳參 復制代碼 |
函數B就是嵌套在函數A中的嵌套函數,它可以繼承函數A的變量和參數,但是B中的變量A是不能訪問的,就好像B給自己的門上了鎖,“只進不出”,我可以拿你的東西,但是你不可以拿我的東西。B這樣就形成了一個自己獨有的封閉空間,這就是一個閉包。
從不同的角度來看:從語法結構上看,函數A包含函數B;從作用域來看,函數B包含函數A,也就是說B能訪問的空間比A大。
因此可以想象得出,假如B函數中還有一個嵌套函數X,那么這個X函數也是一個閉包,作用域包含B和A。這樣下去就形成了一個作用域鏈。
4.閉包
相信通過上面的講解,大家已經懂得了什么是閉包,現在再講講一些關于閉包的特點或者特性吧。
保存變量
什么是保存變量?加入B這個閉包需要兩個變量才能運行,但是剛開始只傳了一個參數進去,所以這時候閉包就會把這個變量的值進行保存,等待第二個變量傳入,而不是丟棄這個變量的值。下面舉一個例子進行說明吧。
| 1 2 3 4 5 6 7 8 9 復制代碼 | function funA(a){function funB(b){return a + b;}return funB;//調用函數B的引用 } var x = funA(2); var sum = x(3); console.log(sum);//輸出結果 5 復制代碼 |
當函數A傳進參數a=2時,這時閉包B就將a進行保存,等到再傳b=3時再進行計算。這就是閉包的保存變量。
5.為什么要使用閉包
使用閉包的最大的好處——避免變量的污染。也就是說你在閉包中聲明的變量不會影響在其他地方也使用這個變量名稱,因為閉包將這個變量鎖在自己的門里面保護起來了,外部是無法修改的。
| 1 2 3 4 5 6 7 8 9 10 11 復制代碼 | function funA(){function funB(b){var a = 'wang';//內部變量 creturn a+b ;}return funB; } var a = 'hua';//外部變量x,是不能改變閉包B中的變量a的 var sum = funA()(a); console.log(a); console.log(sum); 復制代碼 |
可以看出,外部變量是不能修改閉包中的變量a的值的,從而保護了a的值,使其不會受到污染。
閉包的分享就講到這里啦,我相信大家能夠對閉包能夠有一定的了解。當然,由于作者水平有限,這只是個人的見解,有誤的地方還希望多多包涵,或者留言告知我。
我的博客地址:【咕嚕先森的博客】
個人微信公眾號:【咕嚕有得聊】,歡迎關注,一起學習!
總結
以上是生活随笔為你收集整理的闭包 | 浅谈JavaScript闭包问题的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【419天】跃迁之路——程序员高效学习方
- 下一篇: 使用Keras进行深度学习:(二)CNN