函数参数的值是引用传递还是按值传递

在我们给函数传递参数时,被传递的值就会被复制给一个局部变量(即命名参数,或者用arguments对象中的一个元素),而向参数传递引用类型值的时候,会把这个值内存中的地址复制给一个局部变量,因此这个局部变量的变化会反映在函数的外部。请看下面栗子。
function addNum(num){
  num += 10;
  return num;
}
var contNum = 20;
var reseNum = addNum(contNum);
console.log(contNum); //20
console.log(reseNum); //30
addNum()这里的参数是局部变量,在函数调用的时候把contNum作为参数传递,所以contNum的值复制给了参数num,在函数内部参数num的值加上10,但是这一变化不会影响函数外面的contNum变量,因为num和conName这2个只是值相同而并未一样。假如是按引用传递的话,那变量contNum的值应该也是30,从而反应函数内部的修改。当然,使用数据等基本类型值来说明按值传递参数比较简单,但如果使用对象,就不怎么简单了。
function setName (obj){
   obj.name = 'LM';
}
var prseName = new Object();
setName(prseName);
console.log(prseName.name); //LM

我们很多人错误的认为:在局部作用域中修改的对象会在全局作用域中反应出来,就说明值是按引用传递的。
复制代码

在上面的栗子中,参数obj和变量prseName引用的是同一个对象,因为prseName这个传递到setName函数中之后就被复制给了obj。换句话说,即使是按引用传递的,obj也会按引用来访问同一个对象。因此,当在函数内部为obj添加了name属性,函数外部的prseName也将有所接受,因为prseName指向的对象在堆内存中只有一个,而且是全局对象。为了证明是按值传递的,请看下面这个栗子。
function setName (obj){
   obj.name = 'LM';
   obj = new Object();
   obj.name = "RM";
}
var prseName = new Object();
setName(prseName);
console.log(prseName);//LM;
这个栗子与上面的栗子唯一的区别就算添加了2行代码,重新在函数内部为obj定义了一个对象,并且为obj 设置了一个带有不同值的name属性,把prseName传递给setName()函数后,其name属性被设置为"LM",然后又将新对象赋值给obj,同时将其name的值修改为“RM”,如果prse是按引用传递的,那prseName就会自动被修改为指向name属性为“RM”的新对象,但是,当访问prseName.name时,显示的值仍然为“LM”,这就说明,即使在函数内部修改了参数的值,但是在原始的引用上仍然保持不变的,实际上,在函数内部重写obj时,这个变量引用的就是一个局部对象了,而这个局部对象在函数运行完后立即销毁。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值