1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110
| function watch(obj, name, visited = new WeakSet()) { if (obj === null || typeof obj !== 'object' || visited.has(obj)) { return obj; } visited.add(obj); const checkPrototypeChain = (target, property) => { let current = target; while (current) { if (Object.prototype.hasOwnProperty.call(current, property)) { return false; } current = Object.getPrototypeOf(current); if (current && current !== Object.prototype && current !== null) { console.log(`原型链检测:true (对象: ${name}, 属性: ${property})`); return true; } } return false; }; return new Proxy(obj, { get: function (target, property, receiver) { try { if (typeof property === 'symbol' || property === 'constructor' || property === '__proto__') { return Reflect.get(target, property, receiver); }
const value = Reflect.get(target, property, receiver);
if (typeof value === 'object' && value !== null) { const nestedName = `${name}.${String(property)}`; return watch(value, nestedName, visited); }
console.log(`对象 => ${name}, 读取属性: ${String(property)}, 值为: ${typeof value === 'function' ? 'function' : value}, 类型为: ${typeof value}`);
if (!Object.prototype.hasOwnProperty.call(target, property)) { checkPrototypeChain(target, property); }
const descriptor = Object.getOwnPropertyDescriptor(target, property); if (descriptor) { if (descriptor.get || descriptor.set) { console.log(`特殊检测: 存在Getter/Setter (对象: ${name}, 属性: ${String(property)})`); } if (!descriptor.writable && !descriptor.get) { console.log(`特殊检测: 只读属性 (对象: ${name}, 属性: ${String(property)})`); } if (!descriptor.configurable) { console.log(`特殊检测: 不可配置属性 (对象: ${name}, 属性: ${String(property)})`); } } } catch (e) { console.error(`Error in get trap for ${name}.${String(property)}:`, e); } return Reflect.get(target, property, receiver); }, set: (target, property, newValue, receiver) => { try { console.log(`对象 => ${name}, 设置属性: ${String(property)}, 值为: ${typeof newValue === 'function' ? 'function' : newValue}, 类型为: ${typeof newValue}`); } catch (e) { console.error(`Error in set trap for ${name}.${String(property)}:`, e); } return Reflect.set(target, property, newValue, receiver); }, has: function (target, property) { console.log(`对象 => ${name}, in 操作符检测属性: ${String(property)}`); return Reflect.has(target, property); }, deleteProperty: function (target, property) { console.log(`对象 => ${name}, 删除属性: ${String(property)}`); return Reflect.deleteProperty(target, property); }, ownKeys: function (target) { console.log(`对象 => ${name}, 获取自身所有键`); return Reflect.ownKeys(target); }, defineProperty: function (target, property, descriptor) { console.log(`对象 => ${name}, 定义属性: ${String(property)}`); return Reflect.defineProperty(target, property, descriptor); }, setPrototypeOf: function (target, prototype) { console.log(`特殊检测: setPrototypeOf 被调用 (对象: ${name})`); return Reflect.setPrototypeOf(target, prototype); }, getPrototypeOf: function (target) { console.log(`特殊检测: getPrototypeOf 被调用 (对象: ${name})`); return Reflect.getPrototypeOf(target); }, getOwnPropertyDescriptor: function (target, property) { console.log(`特殊检测: getOwnPropertyDescriptor 被调用 (对象: ${name}, 属性: ${String(property)})`); return Reflect.getOwnPropertyDescriptor(target, property); } }); }
|