@
june4 我不知道你的水平,不知道如下表述你能否看懂:
const data = { ... } // 在堆上申请了一个空间,储存对象 { ... },并把指针记为 data
const targetObj = build(data) // 向 build 传入 data 这个指针,build 函数在堆上申请了一个新的空间,储存构造出的对象,并将其指针返回,被你记为 targetObj
// build 执行完后,data 指向源对象,targetObj 指向构造出的对象,gc 回收不了任何对象
const data = () => ({ ... }) // 在堆上申请了一个空间,储存函数 () => ({ ... }),并把指针记为 data
const targetObj = build(data()) // 调用 data 函数,data 函数在堆上申请了一个新的空间,储存构造出的对象 { ... },并将其指针返回;向 build 函数传入 data 返回的对象指针,build 函数在堆上申请了一个新的空间,储存构造出的对象,并将其指针返回,被你记为 targetObj
// build 执行完成后其栈空间会被释放,那个存在于其形参的指向堆源对象的指针也被释放,源对象将在稍后被 gc 回收; targetObj 指向构造出的对象
这两种写法,前者在执行完成后内存占用高( gc 无法回收源对象),后者在执行过程中峰值内存占用高(多出一个函数对象的空间)
另外你一直在用 string 类比,要说明的是,在 JavaScript 中基本类型包括 string 是按值传递的,传入函数时是拷贝,而不是像 object 一样是指针。