let a = []; function test1(){ let ta = Math.random(); let tb = "test2"; let obj1 = { t1: ta } a.push(obj1); } test1();
請問這樣呼叫了之後函數test1還會釋放記憶體嗎? 全域變數a放入了一個物件的引用,該物件在函數test1裡面,為什麼我覺得test1不會釋放記憶體呢?請教一下大家。 。 。 。
认证高级PHP讲师
a和test1共享一個運行上下文,也就是a和test1共存亡吧~不知道我的理解有沒有錯~例如:
function test() { let a = []; function test1(){ let ta = Math.random(); let tb = "test2"; let obj1 = { t1: ta } a.push(obj1); } test1(); } test();
執行完test以後,我認為test1是會釋放的,a也會被釋放。 假如不是在函數中而是直接在window下的話,test1總是存在啊~
之前理解有誤,這應該是兩個問題。
執行完後,test1的變數沒有被直接引用,所以test1的執行環境即上下文應該會被回收,這不是閉包。另外,test1的函數體本身就是屬於其所在上下文的屬性,只要這個上下文還在,這個函數體本身就不會被回收。
先說結論,不是首先閉包的定義就是能夠存取自由變數的函數,在定義上就不符合了
再你的理解有誤 把你的例子改一下
let a = []; function test1(){ let ta = Math.random(); let tb = "test2"; let obj1 = { t1: ta } return obj1; } a.push(test1())
a裡面同樣存在了原obj1指向的對象,但你覺得這還是閉包嗎?
在你的例子裡,test1執行完成後ta,tb,obj1都被釋放了在其中創建的obj1變量指向的對象,由於加入到了a這個全局變量中,在test1執行完後,a[0]指向了這個對象,由於這個對像被a[0]引用,所以不會被釋放,但是和obj1已經沒有關係了,在整個過程中obj1的作用域都沒有改變,a裡面push的是obj1指向的對象而不是obj1
這樣說不知你能不能理解,語文程度太差,感覺講不太清楚= =
a和test1共享一個運行上下文,也就是a和test1共存亡吧~
不知道我的理解有沒有錯~例如:
執行完test以後,我認為test1是會釋放的,a也會被釋放。
假如不是在函數中而是直接在window下的話,test1總是存在啊~
之前理解有誤,這應該是兩個問題。
執行完後,test1的變數沒有被直接引用,所以test1的執行環境即上下文應該會被回收,這不是閉包。另外,test1的函數體本身就是屬於其所在上下文的屬性,只要這個上下文還在,這個函數體本身就不會被回收。
先說結論,不是
首先閉包的定義就是能夠存取自由變數的函數,在定義上就不符合了
再你的理解有誤
把你的例子改一下
a裡面同樣存在了原obj1指向的對象,但你覺得這還是閉包嗎?
在你的例子裡,test1執行完成後ta,tb,obj1都被釋放了
在其中創建的obj1變量指向的對象,由於加入到了a這個全局變量中,在test1執行完後,a[0]指向了這個對象,由於這個對像被a[0]引用,所以不會被釋放,但是和obj1已經沒有關係了,在整個過程中obj1的作用域都沒有改變,a裡面push的是obj1指向的對象而不是obj1
這樣說不知你能不能理解,語文程度太差,感覺講不太清楚= =