Maison > Questions et réponses > le corps du texte
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]
迷茫2017-04-10 15:42:36
楼上的回答中,@kikong 的回答是最靠谱的。
当传递原始类型值给形参时,传递的就是原始值本身。
当传递引用类型值给形参时,传递的是一个指针(一个特殊的值)。
这就是所谓的 JS 中的按值传递。
其实吧,JavaScript 的参数传递涉及两组核心概念:
按值传递和按共享传递(call by value
VS call by sharing
)
重新绑定和变异 (rebinding
VS mutation
)
参数传递的本质其实是一个隐式赋值,赋值运算(=)发生了什么,参数传递就发生了什么。
var num1 = 5
var num = num1
num1
保存着数字类型值 5
,将 num
赋值为 num1
,num
就保存了数字 5。这是按值传递。
var arr1 = [1, 2, 3, 4, 5]
var arr = arr1
arr1
保存一个引用类型值,也可以理解为 arr1
指向数组 [1, 2, 3, 4, 5]的内存地址。将 arr
赋值为 arr1
, arr
也就指向了该数组的内存地址。这是按共享传递(两个变量共享该对象的内存地址)。
var arr1 = [1, 2, 3, 4, 5]
var arr = arr1
arr = [2, 3, 4, 5, 6]
arr
原本与 arr1
一起指向数组 [1, 2, 3, 4, 5] 的内存地址,但通过另一个赋值语句,使 arr
重新指向了数组 [2, 3, 4, 5, 6] 的内存地址。这是重新绑定。
var arr1 = [1, 2, 3, 4, 5]
var arr = arr1
arr1.push(6)
console.log(arr1.length) // => 6
console.log(arr.length) // => 6
任何对 arr1
或 arr
的修改都是对其所指向对象的修改。这是 mutation。
这里尤其需要注意的是 rebinding。对 arr
重新赋值之后,arr1
与 arr
已经指向了不同的内存地址,两者已经断开联系。
在你的例子中,
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]
在执行 add(arr1, 5)
时,传参完成的是隐式的赋值操作(即,arr = arr1, num = 5
),其中传参给 arr
是 按共享传递,传参给 num
是按值传递
在函数体内修改 arr (arr[i] += num
),是 mutation
操作,所以即便 arr
在随后被销毁了,通过 arr1
也能观察到变更。
伊谢尔伦2017-04-10 15:42:36
javascript中的参数传递都采用 按值传递的方式
对于对象来说,这个值是指对象的内存地址
对基本类型,这个值是原始值
=======
function add(arr,num){
console.log(arr);//[1,2,3,4,5];
//arr被重新赋值前和arr1的相同
arr=[5,6,7,8,9];//arr被重新赋值,指向的地址不同,但不会影响arr1的指向,也就是其地址信息
for(var i=0; i<arr.length; i++){
arr[i]+= num;
}
console.log(arr);//[10, 11, 12, 13, 14]
}
var arr1 =[1,2,3,4,5];
add(arr1,5);
console.log(arr1);//[1, 2, 3, 4, 5]
怪我咯2017-04-10 15:42:36
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虽然没有改变,但它也是属于按引用传递的
巴扎黑2017-04-10 15:42:36
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
PHP中文网2017-04-10 15:42:36
http://www.zhihu.com/question/27114726
http://www.zhihu.com/question/25336993
天蓬老师2017-04-10 15:42:36
传递参数:所有函数的参数都是按值传递的。基本类型值的传递如同基本类型变量的复制,而引用类型值的传递,如同引用类型变量的复制。
复制变量值:基础类型会创建一个新值,把值复制到新位置,之后彼此独立。引用类型会复制指针,新老变量(复制和被复制的变量)引用同一个对象,改变其中一个,就会影响另一个。
例子可以参考js高级程序设计第三版4.1.3
ringa_lee2017-04-10 15:42:36
var foo = {
bar: function() { return this.baz; },
baz: 1
};
(function(){
return typeof arguments[0]();//"undefined"
})(foo.bar);
你看这个例子,如果是传递引用,那么foo.bar应该会被当作函数传进去,后面的typeof就不会是undefined了。对吧。