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
相关产品推荐
相关产品推荐

