如何代理Function.prototype?为何自定义set拦截未触发?
问题原因分析
你代码里的console.log('cas')不生效,核心原因是**Function.prototype是不可写属性,你无法直接用Proxy实例替换它**。
具体细节:
- 执行
Object.getOwnPropertyDescriptor(Function, 'prototype')查看该属性特性,会发现它的writable值为false。这意味着你写的Function.prototype = new Proxy(...)赋值操作会静默失败(严格模式下会直接抛出错误)。 - 后续的
Function.prototype._toString = ...和Function.prototype.toString = ...都是在原始的Function.prototype对象上操作,和你创建的Proxy实例没有任何关联,所以代理的set拦截逻辑根本不会触发。
修正思路
如果想对Function.prototype的属性操作做拦截,不能直接替换它,可通过以下方式实现:
- 直接在原
Function.prototype上用Object.defineProperty定义属性,搭配拦截逻辑; - 若要使用Proxy,可以将Proxy作为原型链的扩展,比如让自定义函数继承这个Proxy实例(但内置函数的原型依然是原始
Function.prototype,需根据需求调整)。
举个可运行的示例(拦截对Proxy包装后的原型的属性设置):
const originalProto = Function.prototype; const proxyProto = new Proxy(originalProto, { set(target, property, value) { console.log('cas'); return Reflect.set(target, property, value); } }); // 让自定义函数继承proxyProto来测试拦截 function TestFunc() {} Object.setPrototypeOf(TestFunc, proxyProto); // 给proxyProto添加属性,会触发set拦截 proxyProto.testProp = 'test'; // 控制台会输出'cas'
内容的提问来源于stack exchange,提问作者yg lin
相关产品推荐
相关产品推荐

