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

JavaScript ES6:用全局空对象替代兜底新对象能否提升性能?

用全局单例空对象/数组替代临时创建的空值,确实能带来性能提升!

你的思路非常到位——每次写|| {}或者|| []的时候,其实都在创建一个全新的空对象/数组实例。如果这种代码出现在高频执行的路径里(比如循环、频繁触发的事件回调、或者被反复调用的工具函数),这些临时对象会不断占用内存,给垃圾回收(GC)带来额外压力,日积月累就会影响运行流畅度。

换成全局复用的单例空对象/数组,就能从根源上减少不必要的内存分配和GC开销,具体可以这么做:

  1. 定义冻结的全局单例
    先在模块作用域(推荐,避免污染全局)或者全局作用域里定义这两个常量,并且用Object.freeze冻结它们:

    // 模块级的单例,不会污染全局命名空间
    const EMPTY_OBJECT = Object.freeze({});
    const EMPTY_ARRAY = Object.freeze([]);
    

    为什么要冻结?因为如果后续代码不小心修改了这个空对象(比如someField.thing = 'test'),没冻结的话会直接污染这个全局单例,导致所有依赖它的地方都出现意料之外的属性,冻结之后修改操作会在严格模式下报错,非严格模式下静默失败,能保证单例始终是空的状态。

  2. 替换原有代码
    把原来的兜底逻辑换成单例即可:

    // 原来的写法
    // const someField = (myObject.wantedKey || {});
    // 替换后的写法
    const someField = myObject.wantedKey || EMPTY_OBJECT;
    
    // 原来的数组兜底
    // const nullIsempty = (myObject.undefinedIsEmpty || []);
    // 替换后的写法
    const nullIsempty = myObject.undefinedIsEmpty || EMPTY_ARRAY;
    

关于性能提升的细节

  • 如果是在单次执行的初始化代码里,这种优化几乎感知不到;
  • 但如果是在循环体、高频事件(比如scroll/resize)、或者被频繁调用的函数里,累计的内存分配减少会很明显,GC的停顿次数会降低,整体运行更流畅。

额外的ES6+优化方案

如果你用的是ES2020及以上版本,可以结合**空值合并运算符??和可选链?.**来进一步简化逻辑,同时也能避免临时对象:

// 只针对null/undefined兜底,比||更精准(不会把0、''等假值替换掉)
const someField = myObject.wantedKey ?? EMPTY_OBJECT;

// 如果只是要访问嵌套属性,直接用可选链更简洁,返回undefined而非空对象
const thing = myObject.wantedKey?.thing;

最后再强调一遍:一定要冻结你的单例空对象/数组,否则很容易埋下难以排查的bug!

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.20 12:11:07