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

JavaScript装饰器模式栈溢出问题:简化写法为何报错?

为什么修改后的装饰器写法会触发栈溢出?

这问题其实是函数引用覆盖后的无限递归导致的,咱们一步步拆解来看:

先看正确写法为什么没问题

第一种写法里,你用了一个立即执行函数来包裹逻辑:

instance.run = ((func) => {
  return function() {
    func();
    console.log('decorator run');
  }
})(instance.run);

这里的关键是:立即执行函数执行的瞬间,instance.run还是原Dummy类的run方法,所以func变量保存的是原始方法的引用。当后续调用新的run方法时,func()调用的是最初的那个console.log('run'),完全不会触发递归,自然正常工作。

再看错误写法的问题所在

修改后的get函数里,你直接把instance.run替换成了新函数,但新函数内部又调用了instance.run():

function get() {
  let instance = new Dummy();
  instance.run = function() {
    instance.run(); // 这里的instance.run已经是当前这个新函数了!
    console.log('decorator run');
  }
  return instance;
}

你要注意一个时序问题:当你完成instance.run = function() {...}这个赋值后,instance.run已经指向了这个新的匿名函数。所以当这个新函数执行时,里面的instance.run()其实是在调用它自己,而且没有任何终止条件,就会陷入无限递归——每调用一次就往调用栈里加一层,直到超过JS引擎的栈上限,就抛出了Maximum call stack size exceeded错误。

简单说:你没有保存原方法的引用,反而在新函数里反复调用已经被覆盖的自己,自然就栈溢出了。

内容的提问来源于stack exchange,提问作者Y Bond

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 04:28:54