Javascript的獨特的概念之閉包
目錄
- Javascript閉包簡介:
- 為什么是閉包:
- 總結(jié)
Javascript閉包簡介:
Javascript語言中,有一個獨特的概念:閉包(closure),這在類似C++,Java等編程語言中沒有這個概念。很多高級應(yīng)用都要依靠閉包實現(xiàn)。
為什么是閉包:
或者說,為什么需要閉包,閉包的作用到底是什么?要理解這個概念,首先要理解Javascript中的作用域。
閉包的作用域:
和Java,C/C++等高級編程語言一樣,Javascript也有作用域這個概念。但是,相比而言,它們有很大的區(qū)別。
1). 變量的標(biāo)識:Java,C/C++等編程語言是強(qiáng)類型語言,即變量的聲明需要用類型來標(biāo)識(無論是普通類型,還是自定義類型)。
而Javascript語言是弱類型語言,即不需要用具體的類型來標(biāo)識變量(例如,只需要用var/let,或者都不需要用它們來標(biāo)識)。
2). 變量的作用域:
Javascript:函數(shù)內(nèi)部可以直接讀取全局變量;在函數(shù)外部無法訪問函數(shù)內(nèi)的局部變量。
函數(shù)內(nèi)部聲明的變量,一定要用var來標(biāo)識;如果一個變量沒有標(biāo)識,則這個變量實際上是一個全局變量。
例如:
var x=10; function fun1(){ var y = 20; z = 30; console.log(x); //success } fun1() //console.log(y); //error:Uncaught ReferenceError: y is not defined。 //分析:y是fun1的內(nèi)部變量,在函數(shù)外部方法fun1的內(nèi)部變量y console.log(z); //success:z實際上是全局變量
運行結(jié)果:
10
30
10
閉包的概念以及使用:
可以將閉包理解為: 一個擁有許多變量和綁定了這些變量的環(huán)境的表達(dá)式(通常是一個函數(shù)),因而這些變量也是該表達(dá)式的一部分。
例如:
function fun2(){ var x=100; function fun3(){ console.log(x); } return fun3; } var result=fun2(); result(); //success,輸出100
這就是一個閉包的例子。fun2函數(shù)的返回值賦給result,再執(zhí)行result(),從而訪問到fun2中的fun3函數(shù)的代碼。
有時,我們需要能夠訪問到函數(shù)內(nèi)的局部變量,這時,就需要用閉包來實現(xiàn)。例如,
function fun4(){ var x=100; iAddOne = function(){ x=x*x; } function fun_41(){ console.log(x); } return fun_41; } var res=fun4(); res(); // 10 iAddOne(); res(); // 11
運行結(jié)果:
100
10000
可見,這里,閉包是一個函數(shù)。
閉包的另外一個作用是:
讓閉包表達(dá)式的變量始終保存在內(nèi)存中。因為“變量也是該表達(dá)式的一部分”,所以,在函數(shù)外部擁有來這個閉包表達(dá)式,就相當(dāng)于擁有來表達(dá)式中的變量。
只有在”擁有表達(dá)式的函數(shù)“的生命周期結(jié)束,閉包的生命周期也隨之結(jié)束。
閉包還可以凈化命名空間。
Javascript的一大糟粕就是命名空間沖突。
在C++中,使用using namespace 來進(jìn)行命名空間的聲明和使用;
在java語言中,用import packagename來進(jìn)行區(qū)別。
而在Javascript中,卻沒有這樣的機(jī)制。這樣,很容易引起類似“同名方法的多處定義和引用”而帶來的問題。
因此,有了閉包,在某種程度上,可以減緩這類問題。即內(nèi)部函數(shù)名稱相同,但是外部函數(shù)可以不同名字就行。
例如:
function fun_test() { function fun1(){ var x=100; function fun_common(){ console.log(x); } return fun_common; } function fun2(){ var y=200; function fun_common(){ console.log(y); } return fun_common; } var result1=fun1(); result1(); //success,輸出100 var result2=fun2(); result2(); //success,輸出200 }
運行結(jié)果:
100
200
可見, fun_common分別在fun1和fun2函數(shù)中有定義,在fun_test中可以正確訪問到它們。
總結(jié)
本篇文章就到這里了,希望能夠給你帶來幫助,也希望您能夠多多關(guān)注的更多內(nèi)容!
vv
相關(guān)文章:
1. Intellij IDEA 2019 最新亂碼問題及解決必殺技(必看篇)2. ASP.NET MVC獲取多級類別組合下的產(chǎn)品3. 未來的J2EE主流應(yīng)用框架:對比Spring和EJB34. JS繪圖Flot如何實現(xiàn)動態(tài)可刷新曲線圖5. java實現(xiàn)圖形化界面計算器6. 利用django創(chuàng)建一個簡易的博客網(wǎng)站的示例7. 《javascript設(shè)計模式》學(xué)習(xí)筆記三:Javascript面向?qū)ο蟪绦蛟O(shè)計單例模式原理與實現(xiàn)方法分析8. PHP5.0正式發(fā)布 不完全兼容PHP4 新增多項功能9. JS+css3實現(xiàn)幻燈片輪播圖10. 關(guān)于HTML5的img標(biāo)簽
