JavaScript中函数的参数传递方式都是按值传递
函数传递方式
JavaScript中函数的参数传递方式都是按值传递,没有按引用传递,应该怎么理解??
“能不能举个例子”
补充:保存引用的对象(比如数组,它是按照引用传递的又该怎么理解)
function add(arr,num){
for(var i=0; i<arr.length; i++){
arr[i]+= num;
}
}
var arr1 =[1,2,3,4,5];
add(arr1,5);
console.log(arr1);//[6, 7, 8, 9, 10]
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(8)
楼上的回答中,@kikong 的回答是最靠谱的。
当传递原始类型值给形参时,传递的就是原始值本身。
当传递引用类型值给形参时,传递的是一个指针(一个特殊的值)。
这就是所谓的 JS 中的按值传递。
其实吧,JavaScript 的参数传递涉及两组核心概念:
按值传递和按共享传递(
call by value
VScall by sharing
)重新绑定和变异 (
rebinding
VSmutation
)参数传递的本质其实是一个隐式赋值,赋值运算(=)发生了什么,参数传递就发生了什么。
num1
保存着数字类型值5
,将num
赋值为num1
,num
就保存了数字 5。这是按值传递。arr1
保存一个引用类型值,也可以理解为arr1
指向数组 [1, 2, 3, 4, 5]的内存地址。将arr
赋值为arr1
,arr
也就指向了该数组的内存地址。这是按共享传递(两个变量共享该对象的内存地址)。arr
原本与arr1
一起指向数组 [1, 2, 3, 4, 5] 的内存地址,但通过另一个赋值语句,使arr
重新指向了数组 [2, 3, 4, 5, 6] 的内存地址。这是重新绑定。任何对
arr1
或arr
的修改都是对其所指向对象的修改。这是 mutation。这里尤其需要注意的是 rebinding。对
arr
重新赋值之后,arr1
与arr
已经指向了不同的内存地址,两者已经断开联系。在你的例子中,
在执行
add(arr1, 5)
时,传参完成的是隐式的赋值操作(即,arr = arr1, num = 5
),其中传参给arr
是 按共享传递,传参给num
是按值传递在函数体内修改 arr (
arr[i] += num
),是mutation
操作,所以即便arr
在随后被销毁了,通过arr1
也能观察到变更。javascript中的参数传递都采用 按值传递的方式
对于对象来说,这个值是指对象的内存地址
对基本类型,这个值是原始值
=======
1、按值传递:
按值传递就是将变量先复制一份,然后将复制的变量传入函数,如下面函数,先将num复制,然后再将复制的值传入add函数,执行下面函数就很明了了。
var num=10;
function add(num){
num+=10;
return num;
}
console.log("这是add方法返回的值 "+add(num));//这是add方法返回的值 20
console.log("这是原始的num "+num);//这是原始的num 10
2、按引用传递
按引用传递思想和按值传递一样,先将对象的引用复制一份,然后再将所复制的引用传入函数;不同的是,这两个引用都指向同一个对象。来看一下面的一段代码:
function person(){
this.name="小明";
this.age=23;
}
p1=new person();
p2=new person();
function editName(person){
person.name="小红";
}
console.log(p1.name);//小明
editName(p1);
console.log(p1.name);//小红
注意:不是说可以改变对象的值就是说明是按引用传递,例如以下代码:
function chengeName(p){
p=new person();
p.name="小小";
}
p2=new person();
console.log(p2.name);//小明
chengeName(p2);
console.log(p2.name);//小明
这里p2的name虽然没有改变,但它也是属于按引用传递的
js中函数参数都是按值传递的,即使函数局部改变引起了全局的改变。javascript高级程序设计里是这么说的,可是js里对象哪里有值传递啊。。。
直接传值的话,又哪来的深复制浅复制啊。搞不懂了
function setName(obj) {
obj.name = 'obj';
obj = new Object();
obj.name = 'obj2';
}
var person = new Object();
setName(person);
console.log(person.name);//obj
http://www.zhihu.com/question/27114726
http://www.zhihu.com/question/25336993
传递参数:所有函数的参数都是按值传递的。基本类型值的传递如同基本类型变量的复制,而引用类型值的传递,如同引用类型变量的复制。
复制变量值:基础类型会创建一个新值,把值复制到新位置,之后彼此独立。引用类型会复制指针,新老变量(复制和被复制的变量)引用同一个对象,改变其中一个,就会影响另一个。
例子可以参考js高级程序设计第三版4.1.3
把引用类型的变量想成一堆指针,就是全按值传递。
你看这个例子,如果是传递引用,那么foo.bar应该会被当作函数传进去,后面的typeof就不会是undefined了。对吧。