2017-02-24 61 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

非常感谢!我想我开始明白“标签/指针”的含义......它只是数据地址的“参考”,忽略“参考”指向的位置......第一个和第二个条形函数调用具有相同的第一个参数的“指针”。再次感谢!!! –