You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

将对象按引用传递给函数时出现不符合预期的行为

搞懂JavaScript中对象的“引用传递”误区

兄弟,我太懂你这种困惑了!刚啃JS对象引用这块的时候,很容易被“按引用传递”这个说法带偏,咱们一步步拆解你的问题,把这个坑给踩平。

先看你正常工作的第一段代码

你这段代码逻辑完全没问题,先贴出来再唠:

var c = { why: 'older' };
var d;
d = c; // 这里是把c存储的对象引用值复制给d
function changeGreeting(obj) {
 obj.why = 'newer' ; // 修改的是引用指向的对象本身
}
changeGreeting(d)
console.log(c); // { why: 'newer' }
console.log(d); // { why: 'newer' }

为啥它能成?因为d = c并不是让d和c变成“同一个东西”,而是把c里存的对象引用值(可以理解为指向内存中对象的地址)复制了一份给d。现在c和d是两个独立的变量,但它们都指向内存里同一个对象。

当你在函数里修改obj.why时,你是顺着obj里的引用找到那个共享的对象,直接修改它的属性——所以不管用c还是d去访问这个对象,看到的都是更新后的结果,完全符合预期。

再聊你说的“异常孪生代码”(我猜你是踩了这个坑)

虽然你没写完那段异常代码,但根据我踩过的坑,90%的概率是你在函数里给obj重新赋值了一个新对象,比如这样:

var c = { why: 'older' };
var d;
d = c; 
function changeGreeting(obj) {
 obj = { why: 'newer' }; // 这里是给形参obj重新赋值了新对象
}
changeGreeting(d)
console.log(c); // { why: 'older' } —— 完全没变化!
console.log(d); // { why: 'older' } —— 也没变化!

为啥这次就不行了?核心点在这:JavaScript里所有函数参数都是按值传递的,对象的传递也不例外——这里传递的“值”就是对象的引用值。

当你把d传给函数的obj参数时,其实是把d里的引用值复制了一份给obj。现在d和obj是两个独立的变量,只是暂时指向同一个对象而已。但当你执行obj = { why: 'newer' }时,你是把obj这个变量里的引用值换成了新对象的引用,这和原来的d、c没有任何关系!原来的对象还是安安稳稳待在内存里,c和d依然指向它,所以输出自然还是原来的内容。

最后划几个重点,避免再踩坑

  • 别再纠结“按引用传递”了,JS里没有真正的按引用传递,所有参数都是按值传递,对象传递的是引用的值。
  • 如果想修改原对象,要操作对象的属性(比如obj.xxx = ...),而不是给函数的形参变量重新赋值(obj = 新对象/新值)。
  • 变量(比如c、d、函数里的obj)都是独立的容器,它们只是存储了指向对象的“地址”,修改容器里的“地址”不会影响其他容器里的“地址”。

内容的提问来源于stack exchange,提问作者user9441213

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 03:29:07