《js高级程序设计》上是这样叙述参数传递的:所有函数的参数都是按值传递的,也就是说把函数外部的值复制给函数内部的参数,就和把值从一个变量复制到另一个变量一样。
我们现在来看个面试题:
var a = 1;
var obj = {
b: 2
};
var fn = function () {};
fn.c = 3;
function test(x, y, z) {
x = 4;
y.b = 5;----------(1)
z.c = 6;
return z;
}
test(a, obj, fn);
alert(a + obj.b + fn.c);
首先test传递进去的实参中,a是基本类型。在执行test的时候,x被赋值为4。这个例子很容易理解,实际就是创建了一个a的副本,然后把a的值传入参数中,因为函数中定义了参数的值,所以4就将1覆盖了,但a的值并未发生变化。
obj和 fn都是引用类型。
在上面的例子中,把obj作为参数传入test()中,就有了地址副本,此时obj和y指向了同一个对象,而在y中修改了b属性,其实修改了它们共同指向的对象的b属性,相对应的外部obj所引用的b属性也就改变了。fn同理。所以alert的结果应该是1+5+6 =12.
不过如果(1) 改成y={b:5},那么情况就不一样了。此时我们为y赋了值,也就是说我们把地址副本的指向改变了,指向了新的对象。这样内部的y和外部的 obj就完全没关系了。所以alert的结果应该是1+2+6 =9.
结论:
1、对于数字、字符串等是将它们的值传递给了函数参数,函数参数的改变不会影响函数外部的变量。
2、对于数组和对象等是将对象(数组)的变量的值传递给了函数参数,这个变量保存的指向对象(数组)的地址。当函数改变这个地址指向的对象(数组)的内容时,同时也改变了函数外部变量指向的对象(数组)的内容;当函数改变的是变量的地址时,实际就与函数外部的变量失去了联系,变成了完全不同的对象了,不会对函数外部对象造成改变。
参考资料:
本文深入解析JavaScript中函数参数的传递机制,重点阐述基本类型与引用类型的传递差异,并通过实例展示如何影响外部变量。
347

被折叠的 条评论
为什么被折叠?



