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

JavaScript函数内对象赋值对全局对象值的影响解析

问题原因解析

核心原因是JavaScript的参数传递规则、变量与对象的引用绑定逻辑,和函数作用域的变量隔离特性共同导致的结果,我们逐行拆解逻辑:

示例代码

let obj1 = {
  value: "a"
}

let obj2 = {
  value: "b"
}


function change(obj1, obj2) {
  obj1 = obj2
  obj1.value = "c"
}

change(obj1, obj2);

console.log("obj1: ", obj1, "obj2: ",obj2);
// 输出:obj1:  { value: 'a' } obj2:  { value: 'c' }

核心逻辑拆解

  • 首先明确基础规则:JavaScript中对象类型的值存储在堆内存中,变量本身保存的是指向堆内存对象的引用地址;函数参数是按共享传递的——也就是函数入参拿到的是实参引用地址的副本,函数内部的参数变量属于函数作用域,和外层同名变量是完全独立的两个变量。
  • 调用change(obj1, obj2)的初始阶段:
    • 全局obj1保存指向{value: "a"}对象的地址,全局obj2保存指向{value: "b"}对象的地址
    • 函数内部生成两个局部变量obj1、obj2,分别复制全局两个变量保存的地址:局部obj1初始指向{value:"a"},局部obj2初始指向{value:"b"}
  • 执行函数内第一行obj1 = obj2:
    这行操作只修改函数内部局部obj1保存的地址,把局部obj2持有的地址赋值给它。执行完成后,局部obj1不再指向最初的{value:"a"}对象,转而和局部obj2、全局obj2指向同一个{value:"b"}对象。这步操作完全不会改动全局作用域的obj1,全局obj1始终持有最初指向{value:"a"}的地址。
  • 执行函数内第二行obj1.value = "c":
    这行是给局部obj1当前指向的对象修改属性,由于此时局部obj1指向的就是全局obj2对应的那个对象,修改后这个对象的value属性直接变为"c",所有指向这个对象的变量访问属性时都会拿到新值。

最终结果说明

  • 全局obj1从未被修改过指向,它绑定的{value:"a"}对象也从未被改动过属性,所以最终值保持初始的"a"
  • 全局obj2绑定的对象在函数执行时被修改了value属性,所以最终值为"c"

容易混淆的点:如果删掉函数内的obj1 = obj2语句,直接执行obj1.value = "c",此时局部obj1还指向全局obj1绑定的{value:"a"}对象,修改属性后全局obj1的value也会变成"c"。本质区别是:给变量重新赋值(修改变量保存的引用地址)只会影响当前作用域的变量;而通过引用修改对象本身的属性,所有指向这个对象的变量都会感知到变化。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 05:45:42