首页 > 怎么理解js函数参数为对象时的按值传递?

怎么理解js函数参数为对象时的按值传递?

var person= {
    'name': 'xxx'
}

function change(obj) {
    obj.name = 'eason';
    obj = new Object();
    obj.name = 'jack';
}

change(obj);

假设js是按引用传递的,那么这个函数的参数obj就是对象person的引用? 这时候obj指向了 person 还是直接指向了person 所代表的 那个对象?(person变量和其所代表的对象在不同的地方吧?) 可能一个不恰当的理解就是这时候,obj这个参数是一个指向指针的指针?。。。。。


按照目前的上下文,person(object类型)是存放在栈中的一个变量并且保存了一份它所指向的对象的堆地址,这里的形参obj只是把person在栈中复制了一份给这个obj,最终这里的obj还是指向的这个堆地址,也就是person,obj保持了对同一个对象的引用。


答案: 直接指向了person 所代表的 那个对象.
以下解释存疑, 因为js中难以说清内存是属于堆还是栈, 这种说法完全是为了便于理解, 切不可全听.
person是一个引用类型变量, 实际这个变量也只是个简单变量, 因为他只存储了一个指向某个对象的引用.
person指向的对象才是一个复杂数据类型, 他包括了属性, 方法等一系列东西.
一般认为, person变量是存储在栈内存中, 而他指向的对象存储在堆内存中(此处存疑.)
而对变量的person的操作, 会直接映射到他所指向的对象.
在楼主给出的代码中, change函数中的obj其实只是函数作用域中的一个临时变量, 这牵扯到了函数的问题, 这里顺便说一下.
函数参数只是函数的一个变量而已, 就和全局变量一样的本质, 只是这个变量的作用域只在其所属函数中.
所以以上可以这么来理解, 函数change有一个局部变量obj, 然后接收person做参数, 将person的值赋给了obj变量. 因为person仅仅是存储了一个引用, obj也仅仅是一个引用. 那么到了这个时候, 就有两个引用指向了person指向的对象(person和obj).
好了, 现在执行操作obj.name = 'eason'; 因为obj是指向person所值的对象, 所以这个对象的name属性值会被改变成"eason"(确实是个好名字...), 再往后, obj = new Object();让obj变量又指向了一个新生成的对象, 此时指向perso所指对象的引用就只有一个了, 至此change函数和person所指对象的关系完全断开. 所以对obj的操作, 跟person所指对象一点关系都没有, 只是在操作这个新生成的对象而已, 而这个对象在函数执行结束后, 就被垃圾回收了.
以上正好说明了函数的参数传递是值传递.
欢迎指正~


关于Js的传值机制这里有个简单的解释,如果感觉翻译得比较含糊可以看英文版

【热门文章】
【热门文章】