JavaScript中函数参数的值传递和引用传递

2017-10-17  本文已影响0人  一像素

结论:对于数字、字符串等是将它们的值传递给了函数参数,函数参数的改变不会影响函数外部的变量。

对于数组和对象等是将对象(数组)的变量的值传递给了函数参数,这个变量保存的指向对象(数组)的地址。当函数改变这个地址指向的对象(数组)的内容时,同时也改变了函数外部变量指向的对象(数组)的内容;当函数改变的是变量的地址时,实际就与函数外部的变量失去了联系,变成了完全不同的对象了,不会对函数外部对象造成改变。

很多人认为 JS 中参数有两种传递方式:数字、字符串等按值传递;数组、对象等按地址(引用)传递。其实都是一种值传递。下面的例子很好的说明了这一点。

var v1 = []
var v2 = {};
var v3 = {};
function foo(v1, v2, v3)
{
    v1 = [1];
    v2 = [2];
    v3 = {a:3}
}

foo(v1, v2, v3);
console.log (v1); // 空白 
console.log (v2); // [object Object] 
console.log (v3.a); // undefined
由此可见:v1、v2、v3 都没有被改变,v1 仍然是零个元素的数组,v2、v3 仍然是空白的对象。

但是,数组、对象等按值传递,是指变量地址的值。

数组、对象等的按值传递与数字、字符串还是有所不同的。数字、字符串是把值直接复制进去了,而数组、对象是把变量地址复制进去的。

分析:
前面我们让 v1、v2、v3 作为参数进入函数后,就有了地址副本,这些地址副本的指向和外面的 v1、v2、v3 的地址指向是相同的。但我们为 v1、v2、v3 赋了值,也就是说我们把地址副本的指向改变了,指向了新的数组和对象。这样内部的 v1、v2、v3 和外部的 v1、v2、v3 就完全断了。

如果我们不赋新值,而是直接操作它,那么,它操作到的,仍然是和外面的 v1、v2、v3 指向的同一块数组或对象。

var v1 = []
var v2 = {};
var v3 = {a:0};
function foo(v1, v2, v3)
{
    v1.push (1);
    v2.a = 2;
    v3.a = 3;
}

foo(v1, v2, v3);
console.log (v1); // 1 
console.log (v2.a); // 2 
console.log (v3.a); // 3


function changeStuff(a, b, c)
{
  a = a * 10;
  b.item = "changed";
  c = {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
上一篇下一篇

猜你喜欢

热点阅读