为什么这个代理处理程序会导致无限递归?

Why does this proxy handler cause infinite recursion?

我使用 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 进行了测试。

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