很多人,包括我,受书本知识消化不彻底的影响,认为 JS 中参数有两种传递方式:数字、字符串等按值传递;数组、对象等按地址(引用)传递。对此种观点,我们要谨慎。
/* * JS 按值传递 * 比较test()与test2()的区别 */ var a = []; var b = {}; function test(a1, b1) { a1 = [1, 2]; //a1 指向新的数组 b1 = {a: 1}; //b1 指向新的对象 } //按引用类型的地址的值传递, 执行函数时作用域链中形参和实参指向同一个对象 test(a, b); console.log(a, b); //[] Object {} function test2(a2, b2) { a2.push('a', 'b'); //形参实参指向同一个数组,并在其上操作 b2.a = 1; } test2(a, b); console.log(a, b); //['a', 'b'] Object {a:1}
var v1 = []
var v2 = {};
var v3 = {};
function foo(v1, v2, v3)
{
v1 = [1];
v2 = [2];
v3 = {a:3}
}
foo(v1, v2, v3);
alert (v1); // 空白
alert (v2); // [object Object]
alert (v3.a); // undefined
var v2 = {};
var v3 = {};
function foo(v1, v2, v3)
{
v1 = [1];
v2 = [2];
v3 = {a:3}
}
foo(v1, v2, v3);
alert (v1); // 空白
alert (v2); // [object Object]
alert (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); alert (v1); // 1 alert (v2.a); // 2 alert (v3.a); // 3
转载:http://blog.csdn.net/lijinlin/article/details/6167565