本文將力求最全面旭旭,最普遍的總結(jié)對(duì)閉包的理解
要想了解閉包,首先看一下變量作用域葱跋。
一持寄、變量的作用域。
變量的作用域有兩種:全局變量和局部變量娱俺。
Javascript語言的特殊之處在于:
函數(shù)內(nèi)部可以直接讀取全局變量稍味。在函數(shù)外部自然無法讀取函數(shù)內(nèi)的局部變量。
這里有一個(gè)地方需要注意荠卷,函數(shù)內(nèi)部聲明變量的時(shí)候模庐,一定要使用var命令。如果不用的話油宜,你實(shí)際上聲明了一個(gè)全局變量掂碱!
那么如何從外部讀取局部變量?
正常情況下慎冤,這是辦不到的疼燥,只有通過變通方法才能實(shí)現(xiàn)。那就是在函數(shù)的內(nèi)部蚁堤,再定義一個(gè)函數(shù)醉者。
這就是Javascript語言特有的“鏈?zhǔn)阶饔糜颉?/em>結(jié)構(gòu):子對(duì)象會(huì)一級(jí)一級(jí)地向上尋找所有父對(duì)象的變量。所以披诗,父對(duì)象的所有變量,對(duì)子對(duì)象都是可見的搞莺,反之則不成立。
function fn1(){
n=999;
function fn2(){
alert(n);
}
return fn2;
}
var result=fn1();
result(); // 999
二温圆、閉包的概念
閉包就是能夠讀取其他函數(shù)內(nèi)部變量的函數(shù)岁歉。
由于在Javascript語言中膝蜈,只有函數(shù)內(nèi)部的子函數(shù)才能讀取局部變量熔掺,因此可以把閉包簡(jiǎn)單理解成“定義在一個(gè)函數(shù)內(nèi)部的函數(shù)”非剃。
所以备绽,在本質(zhì)上恨锚,閉包就是將函數(shù)內(nèi)部和函數(shù)外部連接起來的一座橋梁猴伶。
或者換句話說蜗顽,子函數(shù)可以使用父函數(shù)的局部變量
function show() {
var a=12;
function show1(){
alert(a);
}
show1();
}
show();//12
閉包更普遍的一種理解方式:
其實(shí)布卡,很多函數(shù)都存在閉包忿等,廣義的講,所有函數(shù)都可以是閉包;
以下兩種方式都可以形成閉包
(function(){
封閉空間
})()
{
let //es6的定義變量的一種用法
}
閉包另一種更嚴(yán)格的理解方式---詞法環(huán)境
閉包由函數(shù)和與其相關(guān)的引用環(huán)境的組合而成
閉包允許函數(shù)訪問其引用環(huán)境中的變量(又稱自由變量)
廣義上來說娇跟,所有 JavaScript 的函數(shù)都可以成為閉包苞俘,因?yàn)?JavaScript 函數(shù)在創(chuàng)建時(shí)保存了當(dāng)前的詞法環(huán)境。
function add() {
var i = 0;
return function() {
alert(i++);
}
}
var f = add();
f();
f();
三歌亲、閉包延伸
1陷揪、
Js代碼:
function outerFun(){
var a=0;
function innerFun() {
a++;
alert(a);
}
return innerFun; //注意這里
}
var obj=outerFun();
obj(); //結(jié)果為1
obj(); //結(jié)果為2 注意這里說明變量在內(nèi)存不會(huì)被 釋放,因?yàn)殚]包需要它們
var obj2=outerFun();
obj2(); //結(jié)果為1
obj2(); //結(jié)果為2 注意這里說明變量在內(nèi)存不會(huì)被釋放,因?yàn)殚]包需要它們
什么是閉包:
當(dāng)內(nèi)部函數(shù) 在定義它的作用域 的外部被引用時(shí),就創(chuàng)建了該內(nèi)部函數(shù)的閉包 ,
如果內(nèi)部函數(shù)引用了位于外部函數(shù)的變量,當(dāng)外部函數(shù)調(diào)用完畢后,這些變量在內(nèi)存不會(huì)被 釋放,因?yàn)殚]包需要它們.
2滤港、
Js代碼:
var a=13;
function show(){
var a=5;
alert(a);
}
show(); //結(jié)果 5
alert(a); //結(jié)果 13
遮蔽
當(dāng)函數(shù)內(nèi)部和外部同時(shí)定義一個(gè)變量時(shí),這是兩者雖然名字相同脑又,但作用域不同暮胧,沒有毛線關(guān)系,既不會(huì)發(fā)生閉包也不會(huì)產(chǎn)生聯(lián)系问麸,這是遮蔽
3往衷、
Js代碼
function outerFun(){
var a =0;
alert(a);
}
var a=4;
outerFun();
alert(a);
結(jié)果是 0,4 .
因?yàn)樵诤瘮?shù)內(nèi)部使用了var關(guān)鍵字 維護(hù)a的作用域在outFun()內(nèi)部.
再看下面的代碼:
function outerFun(){
//沒有var
a =0;
alert(a);
}
var a=4;
outerFun();
alert(a);
結(jié)果為 0,0 真是奇怪,為什么呢?
作用域鏈是描述一種路徑的術(shù)語,沿著該路徑可以確定變量的值 .
當(dāng)執(zhí)行a=0時(shí),因?yàn)闆]有使用var關(guān)鍵字,因此賦值操作會(huì)沿著作用域鏈到var a=4; 并改變其值
本文為小編參考其他作者觀點(diǎn)結(jié)合自己體會(huì)而進(jìn)行的再創(chuàng)作和總結(jié),主要是為了梳理閉包知識(shí)點(diǎn)严卖,方便讀者閱讀席舍;
參考鏈接:http://www.jb51.net/article/24101.html