JS函数参数传递的疑问,引用类型指针是怎么变化的?

function setName(obj) {
  obj.name = 'Nicholas';
  obj = new Object(); 
  obj.name = "Greg";
  console.log(obj.name); // "Greg"
}
 
var person = new Object();
setName(person);
alert(person.name) 

setName这个函数理解起来有点障碍:person这个对象作为参数传入setName函数,局部参数obj,按照书本的说法按值传递,那么这里的值应该是“指针”,所以,obj复制了一份指向person的指针,obj存放的指针指向的也是person。
接着,又new实例化一个对象,这个对象指针保存在了参数obj中,所以这个时候obj指向了一个新的对象,指向person也就断开了?
然后,后面思路就混乱了,因为obj这只是局部参数,obj.name输出的是Greg。
最后.alert又弹出Nicholas,说明,前面obj断开person的指针又续上了?怎么续上的?
可能表述的不太清楚,主要是不太清楚指针是怎么变化的。

阅读 2.9k
6 个回答

js只有值传递,没有按引用传递,object只是引用类型的值(或者说地址值)。意思是最终都指向值(基本类型值/引用类型值),而不会指向引用的引用。

function setName(obj) {//3: obj -> person -> obj1 
  obj.name = 'Nicholas';//4: obj -> person -> obj1 && obj1.name = 'Nicholas'
  obj = new Object(); //5: obj -> obj2 
  obj.name = "Greg";//6: obj -> obj2  && obj2.name = 'Nicholas'
  console.log(obj.name); //7: console.log obj.name -> obj2.name 'Greg'
}
 
var person = new Object();//1: person -> obj1 
setName(person);//2: person -> obj1
alert(person.name) //8: alert person -> obj1 -> obj1.name  'Nicholas'

首先person传入setName函数没错,obj指向person,所以修改了obj.name相当于person.name='Nicholas';然后obj重新new,这时候就断了,然后附了新值Greg,所以后面输出obj.name就为Greg,然后obj虽然断开了person的指针,但是person本身已经在前面增加了name属性为Nicholas,断开了也没影响啊,所以后面alert为Nicholas

参数传递: 一句话
参数是引用类型(对象),那么参数按值传递,可访问值,不可对原来对象值进行修改(或者说不可以对于变量引用对象的修改)

函数内的obj是person这个指针的副本,在函数内,它先改变原对象的name为“Nicholas”,而后指向另一个对象了,而person仍指向原对象,所以alert出来的是“Nicholas”

var person = new Object();
var obj = person;
obj.name = "name";
obj = new Object();
obj.name = "newName";
console.log(person.name);     // "name"

从上面分析得出obj拷贝的是person的引用类型值,obj赋值为新对象,也不会影响person

var person = new Object();
function setName(obj) {
    // 这里其实就是省略了 var obj = person; obj只是一个局部变量而已
    obj.name = "name";
    obj = new Object();
    obj.name = "newName";
}
setName(person);
console.log(person.name);    // "name"

更加详细可以在这参考

推荐问题