在线观看不卡亚洲电影_亚洲妓女99综合网_91青青青亚洲娱乐在线观看_日韩无码高清综合久久

鍍金池/ 問答/HTML/ 閉包可以讓這些變量的值始終保持在內(nèi)存中,那為什么這樣輸出后還是原來的值

閉包可以讓這些變量的值始終保持在內(nèi)存中,那為什么這樣輸出后還是原來的值

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.每次運行f1,函數(shù)體都會重新執(zhí)行,所以在第二次運行f1后,nAdd函數(shù)體中的n已經(jīng)變成了新的n,值為9

2.全局變量是resultconsult。這句話的f2f1指的是運行上下文,具體到這個問題可以理解為變量nf2

2017年1月6日 17:12
編輯回答
青裙

閉包講清楚不是很容易,我盡量講得清楚些

1.那為什么consult()這里打印出來的不是10,而是9呢?n值不是被保存下來了嗎?
這個問題可以簡化下,實際就是下面這個問題:
var result=f1(); // 內(nèi)存里保存了一個 n
var consult=f1(); // 內(nèi)存里也保存了一個 n 

問題是,但是這兩個 n 是同一個么?

如果是同一個,那就是題主的意思;
不是同一個,就是阮老師的意思;

實際上不是同一個,js權(quán)威指南上是這么說的

clipboard.png

我的理解就是,這個 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)存中了,不過這個不影響閉包的理解)

2018年6月15日 10:01