Y B*_*ond 7 javascript recursion decorator
这是Decorator模式的一个工作示例:
class Dummy {
run() {
console.log('run');
}
}
function get() {
let instance = new Dummy();
instance.run = ((func) => {
return function() {
func();
console.log('decorator run');
}
})(instance.run);
return instance;
}
let obj = get();
obj.run();
Run Code Online (Sandbox Code Playgroud)
但是,如果我们将get函数更改为:
function get() {
let instance = new Dummy();
instance.run = function() {
instance.run();
console.log('decorator run');
}
return instance;
}
Run Code Online (Sandbox Code Playgroud)
我们将面临一个错误: VM68418:6 Uncaught RangeError:Dummy.instance.run(:6:32)超出了最大调用堆栈大小
为什么会这样?所述instance.run仍然是围绕原始方法的包装,而不"无用"附加的自执行的功能.
我很高兴听到答案
在第一个示例中, 的当前值instance.run
保留在func
关闭变量中,然后instance.run
分配一个新值::
instance.run = <old function>
func = instance.run
instance.run = <new function>
// func === <old function> here
Run Code Online (Sandbox Code Playgroud)
因此,当instance.run
调用时func
,它本质上是调用<old function>
。
您可以在不使用 IIFE 的情况下执行相同的操作,只需func
将get()
:
instance.run = <old function>
func = instance.run
instance.run = <new function>
// func === <old function> here
Run Code Online (Sandbox Code Playgroud)
在第二个片段中,instance.run
旧值丢失,并且它有效地调用自身,导致堆栈溢出。