2017-02-24 64 views
1

我覺得這段代碼可能會導致內存泄漏:在Javascript中可以綁定函數導致內存泄漏?

function foo(arr, value){ 
    arr.push(value); 
    console.log(arr); 
} 
var bar = foo.bind(null, []); 
bar('first call');//output: ['first call'] 

//The next thing that confused me is happened, 
//'first call' has been hold in 'arr' after bar('first call') execute: 

bar('second call');//output: ['first call', 'second call']; 

我想知道爲什麼GC不是第一功能之後的第一個函數的參數的參考集合已被執行?

我以爲每次執行bar函數時,形式參數arr都應該初始化爲[]

arr/[]與變量arr2之間的區別是什麼?

var arr2 = []; 
function foo2(value){ 
    arr2.push(value); 
    console.log(arr2); 
} 
var bar2 = foo2.bind(null); 
bar2('first call 2'); 
bar2('second call 2'); 

在此先感謝!

回答

1

您將第一個參數綁定到新數組的概念上,而是綁定到您創建的特定對象,並將其初始化爲新數組。更確切地說,JavaScript中的變量是對象的標籤/指針。許多標籤可以引用同一個對象,並且當底層對象被修改時,每個標籤都會「看到變化」。例外的是原始類型,以及其他不可修改的類型(字符串,日期等),不允許就地修改。

下面的代碼是等價的:

var baz = []; // or baz = new Array(); 
var bar = foo.bind(null, baz); // bind first argument to object pointed to by baz. 
bar('first call'); // operates on baz, making it ['first call'] 
bar('second call'); // operates on baz, making it ['first call', 'second call'] 
baz.push('x'); // ['first call', 'second call', 'x']; 

此外,針對您的問題,這是標準的行爲。在所有其他具有相似語義(Python,Ruby,C#,Java等)的編程語言中,它都差不多。所以只有當foo2永遠活着時,它纔是內存泄漏,但是你希望它能夠短暫地活着。

+0

非常感謝!我想我開始明白「標籤/指針」的含義......它只是數據地址的「參考」,忽略「參考」指向的位置......第一個和第二個條形函數調用具有相同的第一個參數的「指針」。再次感謝!!! –