中一个对象当做参数传递是按值传递还是按引用传递
如果person是按引用传递的,那么person就会自动被修改为指向其name属性值为"Greg"的新对象。但是,当接下来再访问person.name时,显示的值任然是"Nicholas"。这说明即使在函数内部修改了参数的值,但原始的引用任然保持不变。实际上,当在函数内部重写obj时,这个变量引用的就是一个局部对象了。而这个局部对象会在函数执行完毕后立即被销毁。
从上面的例子中,尼古拉得出的结论是:当一个对象当做参数传递时,它是按值传递的。
然而,我们可以肯定的是:当一个引用类型的对象不是当做参数传递时,它是按引用传递的。
我们来看另外一个例子:
var person = new Object();var obj = person;
obj.name = "Nicholas";
obj = new Object();
obj.name = "Greg";
alert(person.name); // "Nicholas"
这个例子中person对象不是当做参数传递的,但person.name的值还是"Nicholas",这和person当做参数传递的情况是一样的。可以确定的是:这个例子中对象是按引用传递的。但按照尼古拉的说法这个例子中对象也是按值传递的。 那么可以得出结论:尼古拉的说法是错的。
我们可用图来说明一下这个问题。
当var person = new Object()时,可以用下面这幅图来描述变量和对象之间的关系:
当var obj = person时,可以用下面这幅图来描述它们之间的关系:
当obj = new Object()时,用下面的图描述它们的关系:
我们可以把Object当成一个中间人,它是联系person与obj的桥梁。之所以改变obj的属性值,会影响person其实是通过Object来传递的。当obj = new Object(),这时obj与Object之间的关系完全断开,与new Object建立了关系。当obj.name = "Greg",此时,obj与"Object"之间已没有关系,当然不会再影响"Object"。
书中的例子是一样的道理:
function setName(obj) {
obj.name = "Nicholas";
obj = new Object();
obj.name = "Greg";
}var person = new Object();
setName(person);
alert(person.name); // "Nicholas"
obj相当于setName函数中的一个局部变量,把person传给函数就相当于var obj = person。其实我们完全可以把这个例子和上面介绍的那个例子看成是等价的,所以上面的图解也适用这个例子。