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

闭包会复制值到新内存地址吗?修改闭包内变量会影响原内存吗?

闭包对引用类型变量的内存操作验证

我写了一段记忆化代码做概念验证,核心想搞清楚:闭包内修改变量时,是直接操作内存里的原始位置?还是创建闭包时会把值复制到新内存位置?

测试结论很明确:对于引用类型(比如这里的Map),闭包不会复制值,而是持有原始对象的引用——所以闭包里修改对象内容时,原始位置的对象会同步变化;但如果给原始变量重新赋值新对象,闭包持有的还是旧引用,不会跟着切换。

class Memoization { 
    cacheInitValue = new Map();
    memoize(f) {
        let cache = this.cacheInitValue;
        return function (...args) {
            let cacheKey = f.name + JSON.stringify(args);
            if (cache.has(cacheKey)) {
                return cache.get(cacheKey);
            }

            let result = f.apply(this, args);
            cache.set(cacheKey, result);
            return result;
        };
    }
}

// 示例1:记忆化普通函数
// ----------------------------------------------------------------

function sum(...numbers) {
    console.log(`sum(${numbers.join(',')}) was called`);
    let total = 0;
    for (let n of numbers) {
        total += n;
    }
    return total;
}

// 使用方式:

let memoSum = new Memoization();
let cacheSum = memoSum.memoize(sum);

console.log(cacheSum(10,20)); // 首次调用,执行sum函数返回结果
console.log(cacheSum(10,20)); // 直接从缓存取结果,sum不会执行

// 查看闭包对memoSum对象属性的修改:

console.log(memoSum.cacheInitValue, "(查看浏览器控制台)"); // 能看到Map的键已经被闭包修改了

// 接下来是关键测试:重置cacheInitValue后再调用记忆化函数

memoSum.cacheInitValue = new Map();

// 再次调用记忆化函数:

console.log(cacheSum(10,20)); // sum会再次执行,因为闭包持有的是旧Map的引用

测试过程解析

  • 第一次调用cacheSum(10,20)时,结果存入cache(即memoSum.cacheInitValue),第二次调用直接取缓存,证明闭包能正常读写这个Map。
  • 打印memoSum.cacheInitValue看到内容变化,说明闭包和外部变量指向的是同一个Map对象,没有复制。
  • 重置memoSum.cacheInitValue为新Map后,cacheSum再次调用时会重新执行sum——因为闭包里的cache变量还是指向原来的旧Map,新Map和闭包没有关联。

内容的提问来源于stack exchange,提问作者Brainiac. jar

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.28 16:56:22