JS参数与垃圾回收

一句话就是 参数你可以理解为相当于在函数内定义了一个局部变量,然后把实参赋值给它。
注意这里连对象都是赋值过去的,并不是引用过去的。直接上代码。

1
2
3
4
5
6
7
8
9
10
11
12
13
function test(num) { num += 10; return num;}
var num = 10;
var res = test(num);console.log(num); //10 外部变量并未受到影响
console.log(res); //20
下面对象不好理解:
function setName(obj) {
obj.name = "James";
}

var person = new Object();
person.name = "Jeremy";
setName(person);
console.log(person.name);//James 影响到了外部引用变量

乍一看,这不就是按引用传递吗?怎么会是按值传递呢?之所以是按值传递是因为当调用setName(person)的时候,实际上是把person所指向的对象的引用进行了复制,然后传递给了setName函数,这样在函数setName内部对此引用进行操作时候是会影响到此引用所指向的对象,即外部person所指向的对象。

总的来说,基本类型的参数传递复制的是具体的值,而引用类型的参数传递复制的是这个引用变量存储的对对象的引用。

为了进一步证明引用类型的参数传递是按值传递而不是按引用传递的,请看:

1
2
3
4
5
6
7
8
9
10
function setName(obj) {
obj.name = "James";
obj = new Object();
obj.name = "dian"
}

var person = new Object();
person.name = "Jimmy";
setName(person);
console.log(person.name);//James

以上代码输出的是James,如果是按引用传递,那么以上代码输出的是dian。实际上,当执行obj.name = “James”的时候,引用所指向的对象的值已经发生了改变,当在对obj进行覆盖的时候,obj的值是一个指向局部对象的引用,而这个引用无法对外部的对象产生影响,并且此对象会在函数执行结束之后销毁。

说说垃圾回收:闭包是最容易引起内存泄漏的。下面是一个小例子。

1
2
3
4
5
6
window.onload = function(){
var el = document.getElementById("id");
el.onclick = function(){
alert(el.id);
}
}

子函数使用外部变量,但是一直没有释放,会造成内存泄漏。

1
2
3
4
5
6
7
8
window.onload = function(){
var el = document.getElementById("id");
var id = el.id; //解除循环引用
el.onclick = function(){
alert(id);
}
el = null; // 将闭包引用的外部函数中活动对象清除。
}