每個(gè)函數(shù)被聲明時(shí)候,就會(huì)攜帶著作用域。
默認(rèn)聲明狀態(tài)下痪欲,其域中有一個(gè)全局對(duì)象(Global Object)悦穿,簡(jiǎn)稱go。因?yàn)榇撕瘮?shù)是包含在window中的业踢,包括在內(nèi)栗柒。當(dāng)函數(shù)被執(zhí)行時(shí),就會(huì)產(chǎn)生自己本身的執(zhí)行上下文(Activation Object)知举,簡(jiǎn)稱ao傍衡。
如果函數(shù)中再放入一層函數(shù),那么新的函數(shù)在被聲明時(shí)依然產(chǎn)生一個(gè)作用域负蠕,不過(guò)里面繼承了外層函數(shù)的勞動(dòng)成果蛙埂,即剛被聲明時(shí),里面就有了全局對(duì)象ao遮糖,和外層函數(shù)本身的ao绣的。如果此函數(shù)被執(zhí)行,也會(huì)形成一個(gè)自己的ao欲账,并放在作用域鏈頂端屡江。這是作用域的規(guī)則,每增加一個(gè)新的執(zhí)行上下文赛不,都會(huì)放入頂端惩嘉,所以按照此邏輯關(guān)系,里層函數(shù)可以讀取外層踢故。當(dāng)一個(gè)函數(shù)執(zhí)行完后文黎,自身的執(zhí)行上下文即被銷毀,不會(huì)重復(fù)使用殿较,如果還需執(zhí)行耸峭,即會(huì)創(chuàng)建一個(gè)新的執(zhí)行上下文。
列舉函數(shù)舉例:
? function a() {
? ? ? function b() {
? ? ? ? ? var testA = 1;
? ? ? ? ? console.log(testB);
? ? ? ? }
? ? ? var testB = 2;
? ? ? return b;
? }
? var testC = a();
? testC();
? ? 執(zhí)行打印結(jié)果為2淋纲;
分析過(guò)程:函數(shù)“b”僅僅在函數(shù)“a”中被聲明劳闹,并未有執(zhí)行事件,所以函數(shù)“b”僅攜帶著全局對(duì)象go與函數(shù)“a”的ao洽瞬,在程序執(zhí)行完函數(shù)“a”之前本涕,因?yàn)椤皉eturn”語(yǔ)句,返回了“b”伙窃,所以函數(shù)“b”攜帶著聲明時(shí)候的作用域被安全送出菩颖。此過(guò)程稱為“閉包”。
函數(shù)“b”攜帶的作用域在外界被執(zhí)行語(yǔ)句執(zhí)行对供,因?yàn)椤白兞縯estB”并未在其內(nèi)部聲明位他,但是由于作用域中作用域鏈關(guān)系氛濒,它攜帶了外界函數(shù)“a”的ao,所以可以訪問(wèn)外部“testB的賦值”鹅髓,所以打印結(jié)果為“2”舞竿。