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

JavaScript返回对象并重置时的引用问题及原因解析

问题:为何需要getObj函数才能实现对象重置?

我尝试创建一个返回对象以及将该对象重置至初始状态的函数,最初的实现如下:

const create = () => ({
    a: "something"
});

const setup = () => {
    let obj = create();

    const reset = () => {
        obj = create();
    }

    return {
        obj,
        reset
    }
}

const { reset, obj: myObj } = setup();

myObj.b = 2;
reset();
console.log("expected to be undefined", myObj.b);

但调用reset函数后,对象并未被重置,myObj.b仍为2。我原本期望myObj的引用保持不变,调用reset后obj指向新对象时myObj也会指向该新对象。

经过调试,改用以下实现后功能正常:

const create = () => ({
    a: "something"
});

const setupWithGet = () => {
    let obj = create();

    const getObj = () => obj;

    const reset = () => {
        obj = create();
    }

    return {
        getObj,
        reset
    }
}

const { reset, getObj } = setupWithGet();

getObj().b = 2;
reset();
console.log("expected to be undefined", getObj().b);

请问为何需要新增getObj这个函数才能实现预期效果?


原因分析

在JavaScript中,变量存储的是对象的引用,但当你在setup函数里返回{ obj, reset }时,obj的值(也就是第一个创建的对象的引用)会被复制一份赋值给myObj。此时myObj和setup内部的obj是两个独立的变量,只是一开始指向同一个对象。

当你调用reset时,setup内部的obj被重新赋值为新创建的对象,但这只会改变内部obj的指向,不会影响外部myObj的指向——myObj依然指向最初的那个对象,所以修改myObj.b后,即使调用reset,myObj还是原来的对象,b自然还存在。

而在第二个实现里,getObj是一个函数,每次调用它都会返回setupWithGet内部当前的obj变量的引用。也就是说:

  • 第一次调用getObj(),返回的是初始创建的对象,你给它加了b:2;
  • 调用reset后,内部的obj指向了新对象;
  • 再次调用getObj(),返回的就是这个新对象,它没有b属性,所以输出undefined,符合预期。

简单来说,直接返回对象引用相当于“一次性传递”,后续内部变量指向变化不会同步到外部;而通过函数返回,则每次都能获取到内部变量当前的指向,实现了引用的动态同步。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.27 01:14:53