手记

死磕JavaScript-函数按值传递参数

早起打卡,今天死磕函数按值传递参数,干货走起......

基本类型的变量传递是将值A复制一份给被传递的变量B,两个变量值得变化是互不干扰的;而引用类型的变量传递是将引用类型变量A的引用传递给被传递的变量B,这个B的变化会反映到A上。例如:

例1:

function addTen(num){
     num += 10;
     return num;
}
var count = 20;
var result = addTen(count);
console.log(count);//20
console.log(result);//30

例2:

function setName(obj){
     obj.name = "javaScript";
}
var language = new Object();
setName(language);
console.log(language.name);//javaScript

这两种函数的值传递是比较好理解的,在例1中,num其实是addTen的局部变量,在调用addTen函数的时候,count将值复制给了局部变量num,虽然函数内部num的值加了10,但是这一变化不会影响给函数外部的count变量。复制前后栈的变化图如下:

在例2中你可能有所疑惑,因为这看起来就像是引用传递啊,不像是标题所说的函数按值传递,这里language的引用复制传递给了obj局部变量,所以是引用传递呀。那我们来看下一个例子:
例3:

function setName(obj){
     obj.name = "javaScript";
     obj = new Object();
     obj.name = "new JavaScript";
}
var language = new Object();
setName(language);
console.log(language.name);//javaScript

如果说language是按引用传递的,那么language就会自动被修改为指向其name属性值为“new JavaScript”的新对象,但结果确实“javaScript”,我们看下复制前后的栈和堆的变化图就能更清楚了。

这下应该能明白了,也就是说这里的函数按值传递中的“值”指的是栈中的值,所以对于引用类型,是将栈中的language的值复制到obj中,也就是说这两个值对应的堆地址是一样的,其在堆中对应的对象是一样的,对obj中的改变对反映到language中,但如果改变了obj的堆地址那么obj和language就没什么关系了。

1人推荐
随时随地看视频
慕课网APP