2012-06-08 119 views
9

在JavaScript函數中是否真的返回Boolean和Numbers引用以外的對象?通過JavaScript引用返回?

這怎麼可能當這些對象被銷燬時,他們所屬的功能終止?

+0

Javascript不是C. – doug65536

回答

17

對象不被破壞,直到所有對它們的引用都消失了,並收集垃圾。當對象返回時,調用代碼獲得對它的引用,並且該對象不被垃圾收集。

從技術上講,當它返回時被調用函數的棧幀被破壞。但是,該對象不在堆棧上,而是在堆上。該函數對對象的本地引用位於堆棧上,因此被銷燬,但調用代碼的引用在一段時間後才被銷燬。

作爲一個方面說明,它返回的方式並不重要,因爲函數返回後無法使用該對象。

+0

當函數返回時,如果函數以影響其外部範圍的方式暴露引用,則激活記錄本身可能會持續存在。也就是說,如果函數實例化一個函數,並且該函數引用本地作用域(激活記錄或「堆棧幀」 - 實際上不是),並且該函數被返回或分配給某個相對全局變量或財產,那麼激活記錄保持可用並且不被收集。 – Pointy

8

確實,在JavaScript函數中,返回除布爾型和數字引用以外的對象?在JavaScript

這是真的,對象總是參照

通過這怎麼可能當這些對象被破壞時,這些都屬於功能,以終止?

只引用被破壞,而不是價值本身。只要沒有引用,這個對象就是被垃圾回收的候選對象。

6

兩個偉大的答案有,但只是想我要補充,這是很容易測試:

function modify(arg) { 
    arg.modified = true; 
} 
test = 4; 
modify(test); 
console.log(test.modified); // undefined 
test = {}; 
modify(test); 
console.log(test.modified); // true 
test = ""; 
modify(test); 
console.log(test.modified); // undefined 

其中不確定意味着它已經被複制,而不是通過引用傳遞。請注意,字符串不是通過引用傳遞的。

2

參數(包括對象)由值發送到一個函數。參數對象的屬性可用且可更改,其行爲與引用類似。看看下面的例子:

function changeObj(obj){obj.a *= 10; return true;} 
function killObj(obj){obj = null; return true;} 
function changeAndKillObj(obj){obj.a += 1; obj = null; return true;} 
var a = {a:1, b:'test'}; 
console.log(a); //Object {a:1, b:'test'} 
changeObj(a); 
console.log(a); //Object {a:10, b:'test'} 
killObj(a); 
console.log(a); //Object {a:10, b:'test'} 
changeAndKillObj(a); //Object {a:11, b:'test'} 

底線:你可以做任何你想要的對象的屬性,但不能與對象本身。對參數的任何賦值都會使其不同的對象並從初始對象中取消鏈接。