【问题标题】:Why does this proxy handler cause infinite recursion?为什么这个代理处理程序会导致无限递归?
【发布时间】:2021-08-30 01:21:09
【问题描述】:

我使用 ES6 代理为 toString 方法构建了一个钩子。在调试一些问题时,我注意到处理程序的console.log 被无缘无故地调用。

class Hook {
    constructor(object) {
        this.object = object;
    }

    toStringProperty() {
        const handler = {
            apply: (target, thisArg, args) => {

                console.log(target, thisArg, args);

                if (thisArg === Function.prototype.toString) {
                    return 'function toString() { [native code] }'
                }

                if (thisArg === this.object) {
                    return "Hooked String"
                }

                return target.apply(thisArg, args)
            }
        }

        Function.prototype.toString = new Proxy(Function.prototype.toString, handler)
    }
}

let hook = new Hook(HTMLAudioElement);
hook.toStringProperty()
HTMLAudioElement.toString();

我花了很多时间试图找出导致这种递归的原因,但我担心我找不到任何东西。

注意:在控制台中输入HTMLAudioElementooo 后也会发生此行为,当然您必须在运行上述代码后执行此操作。我的浏览器是 Chrome。我使用 Devtools Console 进行了测试。

【问题讨论】:

  • 您问题中的 sn-p 似乎没有无限循环。运行它,执行正常结束。
  • @CertainPerformance 如果您等待 2-5 分钟,它将启动。
  • @CertainPerformance 查看我的截图。
  • "我使用 ES6 代理为 toString 方法构建了一个挂钩。" - 不要那样做。如果你必须覆盖Function.prototype.toString(你真的不应该),用普通函数覆盖它,而不是用不必要的代理!
  • 运行 sn-p 15 分钟,我没有看到任何记录。我不认为该函数会随机调用它自己的toString

标签: javascript recursion es6-proxy


【解决方案1】:

在处理程序内部,您调用console.log(target, thisArg, args);,其中targetthisArg 是函数。 devtools 控制台似乎使用.toString() 来获取要显示它的函数的名称。

【讨论】:

  • 另外,造成这种情况的目标也是如此。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-08-13
  • 1970-01-01
  • 2018-11-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多