function f1(){
var n =9;
nAdd=function(){
n=n+1;
}
function f2(){
console.log(n);
}
return f2;
}
var result=f1();
result(); //9
nAdd();
result();// 10
var consult=f1();
consult();//9
如圖代碼所示,正在學(xué)習(xí)閉包,阮老師提到閉包作用之一就是可以讓這些變量的值始終保存在內(nèi)存中,
1.那為什么consult()這里打印出來的不是10,而是9呢?n值不是被保存下來了嗎?
2.還有就是“f2被賦給了一個全局變量,這導(dǎo)致f2始終在內(nèi)存中,而f2的存在依賴于f1,因此f1也始終在內(nèi)存中” 這句話又是什么意思呢?f2為什么被賦給了一個全局變量?這個變量是誰?
閉包講清楚不是很容易,我盡量講得清楚些
1.那為什么consult()這里打印出來的不是10,而是9呢?n值不是被保存下來了嗎?
這個問題可以簡化下,實際就是下面這個問題:
var result=f1(); // 內(nèi)存里保存了一個 n
var consult=f1(); // 內(nèi)存里也保存了一個 n
問題是,但是這兩個 n 是同一個么?
如果是同一個,那就是題主的意思;
不是同一個,就是阮老師的意思;
實際上不是同一個,js權(quán)威指南上是這么說的
我的理解就是,這個 n 是函數(shù)調(diào)用的時候才添加到作用域鏈的,那么兩次調(diào)用函數(shù)賦值給變量,當(dāng)然聲明了兩次,添加了兩次,而且在不同的作用域鏈中,如果是同一個 n 在同一個作用域,不就是重復(fù)聲明了么?你把 var 換成 let 會報錯的,為什么說在不同的作用域鏈中呢?當(dāng)你聲明了 consult 之后,consult的作用域鏈中全局對象里有 result,result的作用域鏈中全局對象里有 consult 嘛?明顯沒有啊,所以兩個 n 在不同的作用域鏈中,當(dāng)然不是同一個;或者再粗淺理解下,你調(diào)用一個函數(shù)兩次賦值給不同變量,難道函數(shù)內(nèi)的變量都是為兩個變量共享,用的是同一個嘛?當(dāng)然不是啊,,,
2.還有就是“f2被賦給了一個全局變量,這導(dǎo)致f2始終在內(nèi)存中,而f2的存在依賴于f1,因此f1也始終在內(nèi)存中” f2為什么被賦給了一個全局變量?這個變量是誰?
var result=f1(); // f1() 函數(shù)執(zhí)行到 return f2,就把 f2 賦值給了 result,result 是全局變量
var consult=f1(); // f1() 函數(shù)執(zhí)行到 return f2,就把 f2 賦值給了 consult,consult 是全局變量
2.還有就是“f2被賦給了一個全局變量,這導(dǎo)致f2始終在內(nèi)存中,而f2的存在依賴于f1,因此f1也始終在內(nèi)存中” 這句話又是什么意思呢?
var result=f1();//result=f2 不完全等價,但是可以用來參考
因為把 f2 賦值給 result,實際上就是在 result 上保存了對 f2的引用,而 f2 里又保存了對 n 的引用,而 f2 和 n 都存在于 f1 的局部環(huán)境里,所以導(dǎo)致了 n,f2,f1 都不會被垃圾回收,也就是說 f2,f1,n 都保存在內(nèi)存中;(因為 js 的垃圾回收機制存在引用計數(shù)的規(guī)則,當(dāng)這個值的引用次數(shù)變成 0 時,這個值才會被垃圾回收,釋放內(nèi)存,引用次數(shù)不為 0 ,就繼續(xù)保存在內(nèi)存中,不會被垃圾回收)
(實際上我覺得 f1 已經(jīng)不在內(nèi)存中了,不過這個不影響閉包的理解)
北大青鳥APTECH成立于1999年。依托北京大學(xué)優(yōu)質(zhì)雄厚的教育資源和背景,秉承“教育改變生活”的發(fā)展理念,致力于培養(yǎng)中國IT技能型緊缺人才,是大數(shù)據(jù)專業(yè)的國家
達(dá)內(nèi)教育集團成立于2002年,是一家由留學(xué)海歸創(chuàng)辦的高端職業(yè)教育培訓(xùn)機構(gòu),是中國一站式人才培養(yǎng)平臺、一站式人才輸送平臺。2014年4月3日在美國成功上市,融資1
北大課工場是北京大學(xué)校辦產(chǎn)業(yè)為響應(yīng)國家深化產(chǎn)教融合/校企合作的政策,積極推進(jìn)“中國制造2025”,實現(xiàn)中華民族偉大復(fù)興的升級產(chǎn)業(yè)鏈。利用北京大學(xué)優(yōu)質(zhì)教育資源及背
博為峰,中國職業(yè)人才培訓(xùn)領(lǐng)域的先行者
曾工作于聯(lián)想擔(dān)任系統(tǒng)開發(fā)工程師,曾在博彥科技股份有限公司擔(dān)任項目經(jīng)理從事移動互聯(lián)網(wǎng)管理及研發(fā)工作,曾創(chuàng)辦藍(lán)懿科技有限責(zé)任公司從事總經(jīng)理職務(wù)負(fù)責(zé)iOS教學(xué)及管理工作。
浪潮集團項目經(jīng)理。精通Java與.NET 技術(shù), 熟練的跨平臺面向?qū)ο箝_發(fā)經(jīng)驗,技術(shù)功底深厚。 授課風(fēng)格 授課風(fēng)格清新自然、條理清晰、主次分明、重點難點突出、引人入勝。
精通HTML5和CSS3;Javascript及主流js庫,具有快速界面開發(fā)的能力,對瀏覽器兼容性、前端性能優(yōu)化等有深入理解。精通網(wǎng)頁制作和網(wǎng)頁游戲開發(fā)。
具有10 年的Java 企業(yè)應(yīng)用開發(fā)經(jīng)驗。曾經(jīng)歷任德國Software AG 技術(shù)顧問,美國Dachieve 系統(tǒng)架構(gòu)師,美國AngelEngineers Inc. 系統(tǒng)架構(gòu)師。