从一个stackoverflow上一个经典的问题开始
function changeStuff(num, obj1, obj2)
{
num = num * 10;
obj1.item = "changed";
obj2 = {item: "changed"};
}
var num = 10;
var obj1 = {item: "unchanged"};
var obj2 = {item: "unchanged"};
changeStuff(num, obj1, obj2);
console.log(num); // 10
console.log(obj1.item); // changed
console.log(obj2.item); // unchanged
传值
函数内的num, obj1, obj2都将是一份新的内存,与调用函数之前定义的三个变量毫无关系。函数内无论怎么修改这三个参数,外部定义的三个变量的值始终不变
传值的意思就是:传内存拷贝。
传引用
函数内的num, obj1, obj2都分别指向一块内存,该内存就是调用函数之前定义的三个变量时创建的内存。函数内对这三个参数所做的任何改动,都将反映到外部定义的三个变量上。
传引用的意思就是:传内存指针
从上面的代码可以看出,JavaScript中函数参数的传递方式既不是传值,也不是传引用,而是叫call-by-sharing
共享传递
In JavaScript, all variables refers to values. So, when we pass a variable to a function, the argument is a value which is itself a reference. This is called call-by-sharing
在JavaScript中,所有变量都是引用值。 所以,当我们将一个变量传递给一个函数时,参数是一个本身就是一个引用的值。 这被称为传递引用。
基本数据类型不可变
var a = 1;
var b = a;
b = 2;
console.log(a); // 1
var a = 1; // 1是number类型,不可变 var b = a; b = 6;
对象类型可变
var a = [1,2,3];
var b = a; // a, b refers to same value
b[2] = 10; // b is mutated
console.log(a);
// output
[1,2,10]
var x = [1,2,3];
var y = x; // x, y refers to same value
y = [4,5,6]; // y is re-assigned
console.log(x);
// output
[1,2,3]
在共享传递中对函数形参的赋值,不会影响实参的值,但对于对象类型,由于对象是可变(mutable),当修改形参对象的属性值,也会影响到实参的属性值。
参考
http://bosn.me/js/js-call-by-sharing/ https://medium.com/wwstay-engineering/javascript-call-by-sharing-2d3ca42c4d02 https://stackoverflow.com/questions/518000/is-javascript-a-pass-by-reference-or-pass-by-value-language http://blog.csdn.net/u012860063/article/details/52840275
comments powered by Disqus