Javascript的獨(dú)特的概念之閉包
目錄
- Javascript閉包簡(jiǎn)介:
- 為什么是閉包:
- 總結(jié)
Javascript閉包簡(jiǎn)介:
Javascript語(yǔ)言中,有一個(gè)獨(dú)特的概念:閉包(closure),這在類似C++,Java等編程語(yǔ)言中沒(méi)有這個(gè)概念。很多高級(jí)應(yīng)用都要依靠閉包實(shí)現(xiàn)。
為什么是閉包:
或者說(shuō),為什么需要閉包,閉包的作用到底是什么?要理解這個(gè)概念,首先要理解Javascript中的作用域。
閉包的作用域:
和Java,C/C++等高級(jí)編程語(yǔ)言一樣,Javascript也有作用域這個(gè)概念。但是,相比而言,它們有很大的區(qū)別。
1). 變量的標(biāo)識(shí):Java,C/C++等編程語(yǔ)言是強(qiáng)類型語(yǔ)言,即變量的聲明需要用類型來(lái)標(biāo)識(shí)(無(wú)論是普通類型,還是自定義類型)。
而Javascript語(yǔ)言是弱類型語(yǔ)言,即不需要用具體的類型來(lái)標(biāo)識(shí)變量(例如,只需要用var/let,或者都不需要用它們來(lái)標(biāo)識(shí))。
2). 變量的作用域:
Javascript:函數(shù)內(nèi)部可以直接讀取全局變量;在函數(shù)外部無(wú)法訪問(wèn)函數(shù)內(nèi)的局部變量。
函數(shù)內(nèi)部聲明的變量,一定要用var來(lái)標(biāo)識(shí);如果一個(gè)變量沒(méi)有標(biāo)識(shí),則這個(gè)變量實(shí)際上是一個(gè)全局變量。
例如:
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實(shí)際上是全局變量
運(yùn)行結(jié)果:
10
30
10
閉包的概念以及使用:
可以將閉包理解為: 一個(gè)擁有許多變量和綁定了這些變量的環(huán)境的表達(dá)式(通常是一個(gè)函數(shù)),因而這些變量也是該表達(dá)式的一部分。
例如:
function fun2(){
var x=100;
function fun3(){
console.log(x);
}
return fun3;
}
var result=fun2();
result(); //success,輸出100
這就是一個(gè)閉包的例子。fun2函數(shù)的返回值賦給result,再執(zhí)行result(),從而訪問(wèn)到fun2中的fun3函數(shù)的代碼。
有時(shí),我們需要能夠訪問(wèn)到函數(shù)內(nèi)的局部變量,這時(shí),就需要用閉包來(lái)實(shí)現(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
運(yùn)行結(jié)果:
100
10000
可見(jiàn),這里,閉包是一個(gè)函數(shù)。
閉包的另外一個(gè)作用是:
讓閉包表達(dá)式的變量始終保存在內(nèi)存中。因?yàn)?ldquo;變量也是該表達(dá)式的一部分”,所以,在函數(shù)外部擁有來(lái)這個(gè)閉包表達(dá)式,就相當(dāng)于擁有來(lái)表達(dá)式中的變量。
只有在”擁有表達(dá)式的函數(shù)“的生命周期結(jié)束,閉包的生命周期也隨之結(jié)束。
閉包還可以凈化命名空間。
Javascript的一大糟粕就是命名空間沖突。
在C++中,使用using namespace 來(lái)進(jìn)行命名空間的聲明和使用;
在java語(yǔ)言中,用import packagename來(lái)進(jìn)行區(qū)別。
而在Javascript中,卻沒(méi)有這樣的機(jī)制。這樣,很容易引起類似“同名方法的多處定義和引用”而帶來(lái)的問(wèn)題。
因此,有了閉包,在某種程度上,可以減緩這類問(wèn)題。即內(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
}
運(yùn)行結(jié)果:
100
200
可見(jiàn), fun_common分別在fun1和fun2函數(shù)中有定義,在fun_test中可以正確訪問(wèn)到它們。
總結(jié)
本篇文章就到這里了,希望能夠給你帶來(lái)幫助,也希望您能夠多多關(guān)注的更多內(nèi)容!
vv
相關(guān)文章:
1. PHP基礎(chǔ)之生成器4——比較生成器和迭代器對(duì)象2. 詳解PHP laravel中的加密與解密函數(shù)3. ASP新手必備的基礎(chǔ)知識(shí)4. asp文件用什么軟件編輯5. 利用Java對(duì)PDF文件進(jìn)行電子簽章的實(shí)戰(zhàn)過(guò)程6. Docker 啟動(dòng)Redis 并設(shè)置密碼的操作7. PHP輸入流php://input的使用分析8. CentOS郵箱服務(wù)器搭建系列——SMTP服務(wù)器的構(gòu)建( Postfix )9. IntelliJ IDEA恢復(fù)刪除文件的方法10. PHP與MYSQL數(shù)據(jù)庫(kù)連接

網(wǎng)公網(wǎng)安備