JS逆向补环境Proxy代理

补环境需要两点
  1. 没有报错
  1. 与浏览器结果一样
 

Proxy代理和Reflect反射

proxy作用>>> 监控对象操作
reflect作用>>> 执行原始操作
let symbol = Symbol(123) let user = { "name": "小明", 1: 2, // [Symbol(123)]:"symbol123", [symbol]: "symbol123", "age":12,// 相当于需要补环境 } // 第一个参数: 原始对象 // 第二个参数: handler 也是对象 let proxyUser = new Proxy(user, { get: function (target, prop, receiver) { /* 三个参数 1. target:原始对象 2. prop: 属性 3. receiver: 代理后的对象 */ // if (typeof prop == "string") { // console.log(`正在获取>>>>> ${prop}`) // } else { // console.log("正在获取", prop) // } console.log(`正在获取>>>>> ${prop.toString()}`) // let result = target[prop];// 不会递归 let result = Reflect.get(target, prop, receiver) // 反射: 执行原始操作 console.log(`返回值>>>>> ${result}`) return result } }) console.log(proxyUser[symbol]); console.log(proxyUser.name); console.log(proxyUser["age"]);
 
 

代理器的封装

在定义函数的时候 需要传值两个参数 1. obj 2. objName、
第一个参数是需要代理的原始对象。
第二个参数是需要代理的原始对象的名字
 
`ld.config.proxy = true;` 这个参数是代表 是否需要代理
 
// 框架代码 ld = {}; ld.config = {}; ld.config.proxy = true; ld.proxy = function proxy(obj, objName) { // obj : 原始对象 // objName: 原始对象的名字。 if (!ld.config.proxy) { return obj } let handler = { get: function (target, prop, receiver) { /* 三个参数 1. target:原始对象 2. prop: 属性 3. receiver: 代理后的对象 */ console.log(`${objName} 对象 正在获取>>>>> ${prop.toString()}`) // let result = target[prop];// 不会递归 let result = Reflect.get(target, prop, receiver) // 反射: 执行原始操作 console.log(`返回值>>>>> ${result}`) return result } }; return new Proxy(obj, handler) } let symbol = Symbol(123) let user = { "name": "小明", 1: 2, // [Symbol(123)]:"symbol123", [symbol]: "symbol123", "age": 12,// 相当于需要补环境 } user = ld.proxy(user, "user") console.log(user[symbol]); console.log(user.name); console.log(user["age"]);
 

Proxy.get方法

 
// 框架代码 ld = {}; ld.config = {}; ld.config.proxy = true; ld.getType = function getType(obj) { return Object.prototype.toString.call(obj) } ld.proxy = function proxy(obj, objName) { // obj : 原始对象 // objName: 原始对象的名字。 if (!ld.config.proxy) { return obj } let handler = { get: function (target, prop, receiver) { let result; try {// 防止报错 result = Reflect.get(target, prop, receiver) /* 如果迭代对象 可以使用JSON.stringify 但是考虑到循环引用不能显示,所以不推荐。 console.log(`get|obj:【${objName}】 正在获取属性prop——> 【${prop}】 result====> 【${JSON.stringify(result)}】`); */ let type = ld.getType(result) if (result instanceof Object) { console.log(`get|obj:【${objName}】 正在获取属性prop——> 【${prop.toString()}】 type====> 【${type}】`); // 需要递归对象 result = ld.proxy(result, `${objName}.${prop.toString()}`); } else { console.log(`get|obj:【${objName}】 正在获取属性prop——> 【${prop.toString()}】 result====> 【${result}】`); } } catch (e) { console.log(`error====> 【${e.message}】 get|obj:【${objName}】 正在获取属性prop——> 【${prop.toString()}】`); } return result; } }; return new Proxy(obj, handler) } user = { "username": "xm", "info": { "name": "小明", "age": 12, } } user = ld.proxy(user, "user") console.log(user.info) console.log(user.info.name)
 
notion image

Proxy.set方法

 
修改了获取对象的参数类型报错问题。(symbol类型报错)
 
// 框架代码 ld = {}; ld.config = {}; ld.config.proxy = true; // 代理开关 ld.getType = function getType(obj) { return Object.prototype.toString.call(obj) } ld.proxy = function proxy(obj, objName) { // obj : 原始对象 // objName: 原始对象的名字。 if (!ld.config.proxy) { return obj } let handler = { get: function (target, prop, receiver) { let result; try {// 防止报错 result = Reflect.get(target, prop, receiver) /* 如果迭代对象 可以使用JSON.stringify 但是考虑到循环引用不能显示,所以不推荐。 console.log(`get|obj:【${objName}】 正在获取属性prop——> 【${prop}】 result====> 【${JSON.stringify(result)}】`); */ let type = ld.getType(result) if (result instanceof Object) { console.log(`get|obj:【${objName}】 正在获取属性(prop)——> 【${prop.toString()}】 type====> 【${type}】`); // 需要递归对象 result = ld.proxy(result, `${objName}.${prop.toString()}`); } else { console.log(`get|obj:【${objName}】 正在获取属性(prop)——> 【${prop.toString()}】 result====> 【${result}】`); } } catch (e) { console.log(`!error! ====> 【${e.message}】 get|obj:【${objName}】 正在获取属性(prop)——> 【${prop.toString()}】`); } return result; }, set: function (target, prop, value, receiver) { let result try { result = Reflect.set(target, prop, value, receiver); let type = ld.getType(value) if (value instanceof Object) { console.log(`set|obj:【${objName}】 正在获取属性(prop)——> 【${prop.toString()}】 type====> 【${type}】`); // 需要递归对象 } else { console.log(`set|obj:【${objName}】 正在设置属性(prop)——> 【${prop.toString()}】 value ====> 【${value}】`); } } catch (e) { console.log(`!error! ====> 【${e.message}】 set|obj:【${objName}】 正在设置属性(prop)——> 【${prop.toString()}】`); } return result } }; return new Proxy(obj, handler) } let symbol = Symbol(123) user = { "username": "xm", "info": { "name": "小明", "age": 12, }, [symbol]: "symbol123" } user = ld.proxy(user, "user") // 获取对象 console.log(user.info) // 獲取symbol類型 console.log(user[symbol]) console.log("=".repeat(100)) // 设置单一属性 user.test = 123 // 设置对象 user.study = { "math": 100, } console.log(user.study.math);
notion image

拦截属性描述符 getOwnPropertyDescriptor

当我们获取value的时候进行拦截
 
增加了 `let type = ld.getType(result)`
根据type = undefined 然后具体判断
 
// 框架代码 ld = {}; ld.config = {}; ld.config.proxy = true; // 代理开关 ld.getType = function getType(obj) { return Object.prototype.toString.call(obj) } ld.proxy = function proxy(obj, objName) { // obj : 原始对象 // objName: 原始对象的名字。 if (!ld.config.proxy) { return obj } let handler = { get: function (target, prop, receiver) { let result; try {// 防止报错 result = Reflect.get(target, prop, receiver) /* 如果迭代对象 可以使用JSON.stringify 但是考虑到循环引用不能显示,所以不推荐。 console.log(`get|obj:【${objName}】 正在获取属性prop——> 【${prop}】 result====> 【${JSON.stringify(result)}】`); */ let type = ld.getType(result) if (result instanceof Object) { console.log(`get|obj:【${objName}】 正在获取属性(prop)——> 【${prop.toString()}】 type====> 【${type}】`); // 需要递归对象 result = ld.proxy(result, `${objName}.${prop.toString()}`); } else { console.log(`get|obj:【${objName}】 正在获取属性(prop)——> 【${prop.toString()}】 result====> 【${result}】`); } } catch (e) { console.log(`!error! ====> 【${e.message}】 get|obj:【${objName}】 正在获取属性(prop)——> 【${prop.toString()}】`); } return result; }, set: function (target, prop, value, receiver) { let result try { result = Reflect.set(target, prop, value, receiver); let type = ld.getType(value) if (value instanceof Object) { console.log(`set|obj:【${objName}】 正在获取属性(prop)——> 【${prop.toString()}】 type====> 【${type}】`); // 需要递归对象 } else { console.log(`set|obj:【${objName}】 正在设置属性(prop)——> 【${prop.toString()}】 value ====> 【${value}】`); } } catch (e) { console.log(`!error! ====> 【${e.message}】 set|obj:【${objName}】 正在设置属性(prop)——> 【${prop.toString()}】`); } return result }, getOwnPropertyDescriptor(target, prop) { let result; // 返回结果有两种情况 第一种undefined,还有一种是描述符对象 try { result = Reflect.getOwnPropertyDescriptor(target, prop); let type = ld.getType(result) console.log(`getOwnPropertyDescriptor |obj:【${objName}】 (prop)——> 【${prop.toString()}】 type====> 【${type}】`); if (typeof result !== "undefined") { result = ld.proxy(result,`${objName}.${prop.toString()}.PropertyDescriptor`); } } catch (e) { console.log(`!error! ====> 【${e.message}】 getOwnPropertyDescriptor|obj:【${objName}】 (prop)——> 【${prop.toString()}】`); } return result; } }; return new Proxy(obj, handler) } let user = { "name": "xm" } user = ld.proxy(user, "user") console.log(Object.getOwnPropertyDescriptor(user, "name").value)
notion image
 
 

拦截属性定义 defineProperty

自定义添加数据时拦截
 
// 框架代码 ld = {}; ld.config = {}; ld.config.proxy = true; // 代理开关 ld.getType = function getType(obj) { return Object.prototype.toString.call(obj) } ld.proxy = function proxy(obj, objName) { // obj : 原始对象 // objName: 原始对象的名字。 if (!ld.config.proxy) { return obj } let handler = { get: function (target, prop, receiver) { let result; try {// 防止报错 result = Reflect.get(target, prop, receiver) /* 如果迭代对象 可以使用JSON.stringify 但是考虑到循环引用不能显示,所以不推荐。 console.log(`get|obj:【${objName}】 正在获取属性prop——> 【${prop}】 result====> 【${JSON.stringify(result)}】`); */ let type = ld.getType(result) if (result instanceof Object) { console.log(`get|obj:【${objName}】 正在获取属性(prop)——> 【${prop.toString()}】 type====> 【${type}】`); // 需要递归对象 result = ld.proxy(result, `${objName}.${prop.toString()}`); } else { console.log(`get|obj:【${objName}】 正在获取属性(prop)——> 【${prop.toString()}】 result====> 【${result}】`); } } catch (e) { console.log(`!error! ====> 【${e.message}】 get|obj:【${objName}】 正在获取属性(prop)——> 【${prop.toString()}】`); } return result; }, set: function (target, prop, value, receiver) { let result try { result = Reflect.set(target, prop, value, receiver); let type = ld.getType(value) if (value instanceof Object) { console.log(`set|obj:【${objName}】 正在获取属性(prop)——> 【${prop.toString()}】 type====> 【${type}】`); // 需要递归对象 } else { console.log(`set|obj:【${objName}】 正在设置属性(prop)——> 【${prop.toString()}】 value ====> 【${value}】`); } } catch (e) { console.log(`!error! ====> 【${e.message}】 set|obj:【${objName}】 正在设置属性(prop)——> 【${prop.toString()}】`); } return result }, getOwnPropertyDescriptor(target, prop) { let result; // 返回结果有两种情况 第一种undefined,还有一种是描述符对象 try { result = Reflect.getOwnPropertyDescriptor(target, prop); let type = ld.getType(result) console.log(`getOwnPropertyDescriptor |obj:【${objName}】 (prop)——> 【${prop.toString()}】 type====> 【${type}】`); // 不会对描述符进行拦截,拦截也可以 信息太多了 没必要 if (typeof result !== "undefined") { result = ld.proxy(result,`${objName}.${prop.toString()}.PropertyDescriptor`); } } catch (e) { console.log(`!error! ====> 【${e.message}】 getOwnPropertyDescriptor|obj:【${objName}】 (prop)——> 【${prop.toString()}】`); } return result; }, defineProperty:function (target,prop,descriptor){ let result; // 直接回调 try{ result = Reflect.defineProperty(target,prop,descriptor); console.log(`defineProperty |obj:【${objName}】 (prop)——> 【${prop.toString()}】`); } catch (e){ console.log(`!error! ====> 【${e.message}】 defineProperty|obj:【${objName}】 (prop)——> 【${prop.toString()}】`); } return result } }; return new Proxy(obj, handler) } let user = { } user = ld.proxy(user,"user") user.name = "xm"
notion image

Proxy.apply 方法

 
拦截apply方法
 
// 拦截函数调用 // 框架代码 ld = {}; ld.config = {}; ld.config.proxy = true; // 代理开关 ld.getType = function getType(obj) { return Object.prototype.toString.call(obj) } ld.proxy = function proxy(obj, objName) { // obj : 原始对象 // objName: 原始对象的名字。 if (!ld.config.proxy) { return obj } let handler = { get: function (target, prop, receiver) { let result; try {// 防止报错 result = Reflect.get(target, prop, receiver) /* 如果迭代对象 可以使用JSON.stringify 但是考虑到循环引用不能显示,所以不推荐。 console.log(`get|obj:【${objName}】 正在获取属性prop——> 【${prop}】 result====> 【${JSON.stringify(result)}】`); */ let type = ld.getType(result) if (result instanceof Object) { console.log(`get|obj:【${objName}】 正在获取属性(prop)——> 【${prop.toString()}】 type====> 【${type}】`); // 需要递归对象 result = ld.proxy(result, `${objName}.${prop.toString()}`); } else { console.log(`get|obj:【${objName}】 正在获取属性(prop)——> 【${prop.toString()}】 result====> 【${result}】`); } } catch (e) { console.log(`!error! ====> 【${e.message}】 get|obj:【${objName}】 正在获取属性(prop)——> 【${prop.toString()}】`); } return result; }, set: function (target, prop, value, receiver) { let result try { result = Reflect.set(target, prop, value, receiver); let type = ld.getType(value) if (value instanceof Object) { console.log(`set|obj:【${objName}】 正在获取属性(prop)——> 【${prop.toString()}】 type====> 【${type}】`); // 需要递归对象 } else { console.log(`set|obj:【${objName}】 正在设置属性(prop)——> 【${prop.toString()}】 value ====> 【${value}】`); } } catch (e) { console.log(`!error! ====> 【${e.message}】 set|obj:【${objName}】 正在设置属性(prop)——> 【${prop.toString()}】`); } return result }, getOwnPropertyDescriptor(target, prop) { let result; // 返回结果有两种情况 第一种undefined,还有一种是描述符对象 try { result = Reflect.getOwnPropertyDescriptor(target, prop); let type = ld.getType(result) console.log(`getOwnPropertyDescriptor |obj:【${objName}】 (prop)——> 【${prop.toString()}】 type====> 【${type}】`); // 不会对描述符进行拦截,拦截也可以 信息太多了 没必要 if (typeof result !== "undefined") { result = ld.proxy(result, `${objName}.${prop.toString()}.PropertyDescriptor`); } } catch (e) { console.log(`!error! ====> 【${e.message}】 getOwnPropertyDescriptor|obj:【${objName}】 (prop)——> 【${prop.toString()}】`); } return result; }, defineProperty: function (target, prop, descriptor) { let result; // 直接回调 try { result = Reflect.defineProperty(target, prop, descriptor); console.log(`defineProperty |obj:【${objName}】 (prop)——> 【${prop.toString()}】`); } catch (e) { console.log(`!error! ====> 【${e.message}】 defineProperty|obj:【${objName}】 (prop)——> 【${prop.toString()}】`); } return result }, apply: function (target, thisArgs, argumentList) { /* target : 函数对象 thisArgs: 调用函数的this指针 argumentList: 数组 列表 函数的入参组成的列表, 同JS中的apply方法。 */ let result; try { result = Reflect.apply(target, thisArgs, argumentList); let type = ld.getType(result) if (result instanceof Object) { console.log(`apply|function :【${objName}】 result:[${result}]`); } else if (typeof result === "symbol") { console.log(`apply|function :【${objName}】 result:[${result.toString()}]`); } else { console.log(`apply|function :【${objName}】, result:[${result}]`); } } catch (e) { console.log(`apply|function :【${objName}】 !error! ====> 【${e.message}】 `); } return result } }; return new Proxy(obj, handler) } function add(a, b) { return a } add = ld.proxy(add, "add") console.log(add(Symbol(), 2))
notion image

Proxy.construct 方法

针对New关键词进行拦截
// 拦截函数调用 // 框架代码 ld = {}; ld.config = {}; ld.config.proxy = true; // 代理开关 ld.getType = function getType(obj) { return Object.prototype.toString.call(obj) } ld.proxy = function proxy(obj, objName) { // obj : 原始对象 // objName: 原始对象的名字。 if (!ld.config.proxy) { return obj } let handler = { get: function (target, prop, receiver) { let result; try {// 防止报错 result = Reflect.get(target, prop, receiver) /* 如果迭代对象 可以使用JSON.stringify 但是考虑到循环引用不能显示,所以不推荐。 console.log(`get|obj:【${objName}】 正在获取属性prop——> 【${prop}】 result====> 【${JSON.stringify(result)}】`); */ let type = ld.getType(result) if (result instanceof Object) { console.log(`get|obj:【${objName}】 正在获取属性(prop)——> 【${prop.toString()}】 type====> 【${type}】`); // 需要递归对象 result = ld.proxy(result, `${objName}.${prop.toString()}`); } else { console.log(`get|obj:【${objName}】 正在获取属性(prop)——> 【${prop.toString()}】 result====> 【${result}】`); } } catch (e) { console.log(`!error! ====> 【${e.message}】 get|obj:【${objName}】 正在获取属性(prop)——> 【${prop.toString()}】`); } return result; }, set: function (target, prop, value, receiver) { let result try { result = Reflect.set(target, prop, value, receiver); let type = ld.getType(value) if (value instanceof Object) { console.log(`set|obj:【${objName}】 正在获取属性(prop)——> 【${prop.toString()}】 type====> 【${type}】`); // 需要递归对象 } else { console.log(`set|obj:【${objName}】 正在设置属性(prop)——> 【${prop.toString()}】 value ====> 【${value}】`); } } catch (e) { console.log(`!error! ====> 【${e.message}】 set|obj:【${objName}】 正在设置属性(prop)——> 【${prop.toString()}】`); } return result }, getOwnPropertyDescriptor(target, prop) { let result; // 返回结果有两种情况 第一种undefined,还有一种是描述符对象 try { result = Reflect.getOwnPropertyDescriptor(target, prop); let type = ld.getType(result) console.log(`getOwnPropertyDescriptor |obj:【${objName}】 (prop)——> 【${prop.toString()}】 type====> 【${type}】`); // 不会对描述符进行拦截,拦截也可以 信息太多了 没必要 if (typeof result !== "undefined") { result = ld.proxy(result, `${objName}.${prop.toString()}.PropertyDescriptor`); } } catch (e) { console.log(`!error! ====> 【${e.message}】 getOwnPropertyDescriptor|obj:【${objName}】 (prop)——> 【${prop.toString()}】`); } return result; }, defineProperty: function (target, prop, descriptor) { let result; // 直接回调 try { result = Reflect.defineProperty(target, prop, descriptor); console.log(`defineProperty |obj:【${objName}】 (prop)——> 【${prop.toString()}】`); } catch (e) { console.log(`!error! ====> 【${e.message}】 defineProperty|obj:【${objName}】 (prop)——> 【${prop.toString()}】`); } return result }, apply: function (target, thisArgs, argumentList) { /* target : 函数对象 thisArgs: 调用函数的this指针 argumentList: 数组 列表 函数的入参组成的列表, 同JS中的apply方法。 */ let result; try { result = Reflect.apply(target, thisArgs, argumentList); let type = ld.getType(result) if (result instanceof Object) { console.log(`apply|function :【${objName}】 result:[${result}]`); } else if (typeof result === "symbol") { console.log(`apply|function :【${objName}】 result:[${result.toString()}]`); } else { console.log(`apply|function :【${objName}】, result:[${result}]`); } } catch (e) { console.log(`apply|function :【${objName}】 !error! ====> 【${e.message}】 `); } return result }, construct: function (target, argumentsList, newTarget) { /* target: 函数对象 argumentsList: 关键字传进来的参数 是一个列表 newTarget: 代理后的对象 */ let result; try { result = Reflect.construct(target, argumentsList, newTarget); let type = ld.getType(result); console.log(`construct|function :【${objName}】 type:[${type}]`); } catch (e) { console.log(`construct|function :【${objName}】 !error! ====> 【${e.message}】 `); } return result } }; return new Proxy(obj, handler) } // 针对New关键词进行拦截 function User(){ } Object.defineProperty(User.prototype,Symbol.toStringTag,{ value:"UserTest " }) User = ld.proxy(User,"User") user = new User()
 
notion image
 

其他的拦截方法

 

deleteProperty

拦截对对象属性的 delete 操作
deleteProperty(target, propKey) { let result; result = Reflect.deleteProperty(target, propKey); console.log(`{deleteProperty|obj:[${objName}] ——> prop:[${propKey.toString()}], result:[${result}]}`); return result; }
调用
user = { "name":"小明" } user = ld.proxy(user,"user") delete user.name
notion image
 
注意>>>> 如果使用属性描述符定义就不能删除
user = { "name": "小明" } Object.defineProperty(user, "age", { configurable: false, value: 10 }) user = ld.proxy(user, "user") delete user.age console.log(user.age) delete user.name console.log(user.name)
结果返回false || age 仍能被打印 但name就不行了
notion image

has

针对 in 操作字符串的代理方法
has(target, propKey) { let result; result = Reflect.has(target, propKey); console.log(`{has|obj:[${objName}] ——> prop:[${propKey.toString()}], result:[${result}]}`); return result; }
 
調用
user = { "name": "小明" } Object.defineProperty(user, "age", { configurable: false, value: 10 }) user = ld.proxy(user, "user") delete user.age console.log(user.age) delete user.name console.log(user.name) console.log("age" in user) console.log("name" in user)
notion image

ownKeys

拦截自身属性遍历。
获取对象所有自身可枚举属性构成的一个数组
ownKeys(target) { let result; result = Reflect.ownKeys(target); console.log(`{ownKeys|obj:[${objName}]}`) return result }
 
调用
user = { "name": "小明" } Object.defineProperty(user, "age", { configurable: false, value: 10 }) user = ld.proxy(user, "user") delete user.age console.log(user.age) // delete user.name // console.log(user.name) // 判断属性是否存在 console.log("age" in user) console.log("name" in user) // 针对拦截自身属性遍历 console.log(Object.keys(user))
 
notion image
 
但是age 并没有被遍历到 所以我们还需要修改下
enumerable:true,// 是否可枚举
user = { "name": "小明" } Object.defineProperty(user, "age", { configurable: false, // 是否可配置 value: 10, enumerable:true,// 是否可枚举 }) user = ld.proxy(user, "user") delete user.age console.log(user.age) // delete user.name // console.log(user.name) // 判断属性是否存在 console.log("age" in user) console.log("name" in user) // 针对拦截自身属性遍历 console.log(Object.keys(user))
结果
notion image
 
 

getPrototypeOf、setPrototypeOf

getPrototypeOf(target) { let result; result = Reflect.getPrototypeOf(target); console.log(`{getPrototypeOf|obj:[${objName}]`); return result; }, setPrototypeOf(target, proto) { let result; result = Reflect.setPrototypeOf(target, proto); console.log(`{setPrototypeOf|obj:[${objName}]`); return result; }
调用
// 获取原型对象 console.log(user.__proto__) // 设置原型对象 let testObj = {}; console.log(user.__proto__ = testObj)
 
notion image
 

isExtensible

用于拦截对象的Object.isExtensible()
preventExtensions(target) { let result; result = Reflect.preventExtensions(target); console.log(`{preventExtensions|obj:[${objName}]}`) return result },

preventExtensions()

用于拦截对象的Object.isExtensible()
isExtensible(target) { let result; result = Reflect.isExtensible(target); console.log(`{isExtensible|obj:[${objName}]}`) return result }
 

完全体代码

// 框架代码 ld = {}; ld.config = {}; ld.config.proxy = true; // 代理开关 ld.getType = function getType(obj) { return Object.prototype.toString.call(obj) } ld.proxy = function proxy(obj, objName) { // obj : 原始对象 // objName: 原始对象的名字。 if (!ld.config.proxy) { return obj } let handler = { get: function (target, prop, receiver) { let result; try {// 防止报错 result = Reflect.get(target, prop, receiver) /* 如果迭代对象 可以使用JSON.stringify 但是考虑到循环引用不能显示,所以不推荐。 console.log(`get|obj:【${objName}】 正在获取属性prop——> 【${prop}】 result====> 【${JSON.stringify(result)}】`); */ let type = ld.getType(result) if (result instanceof Object) { console.log(`get|obj:【${objName}】 正在获取属性(prop)——> 【${prop.toString()}】 type====> 【${type}】`); // 需要递归对象 result = ld.proxy(result, `${objName}.${prop.toString()}`); } else if (typeof result === "symbol") { console.log(`get|obj:【${objName}】 正在获取属性(prop)——> 【${prop.toString()}】 result====> 【${result.toString()}】`); }else { console.log(`get|obj:【${objName}】 正在获取属性(prop)——> 【${prop.toString()}】 result====> 【${result}】`); } } catch (e) { console.log(`!error! ====> 【${e.message}】 get|obj:【${objName}】 正在获取属性(prop)——> 【${prop.toString()}】`); } return result; }, set: function (target, prop, value, receiver) { let result try { result = Reflect.set(target, prop, value, receiver); let type = ld.getType(value) if (value instanceof Object) { console.log(`set|obj:【${objName}】 正在设置属性(prop)——> 【${prop.toString()}】 type====> 【${type}】`); // 需要递归对象 } else if (typeof value === "symbol") { console.log(`set|obj:【${objName}】 正在设置属性(prop)——> 【${prop.toString()}】 value ====> 【${value.toString()}】`); } else { console.log(`set|obj:【${objName}】 正在设置属性(prop)——> 【${prop.toString()}】 value ====> 【${value}】`); } } catch (e) { console.log(`!error! ====> 【${e.message}】 set|obj:【${objName}】 正在设置属性(prop)——> 【${prop.toString()}】`); } return result }, getOwnPropertyDescriptor(target, prop) { let result; // 返回结果有两种情况 第一种undefined,还有一种是描述符对象 try { result = Reflect.getOwnPropertyDescriptor(target, prop); let type = ld.getType(result) console.log(`getOwnPropertyDescriptor |obj:【${objName}】 (prop)——> 【${prop.toString()}】 type====> 【${type}】`); // // 不会对描述符进行拦截,拦截也可以 信息太多了 没必要 // if (typeof result !== "undefined") { // result = ld.proxy(result, `${objName}.${prop.toString()}.PropertyDescriptor`); // } } catch (e) { console.log(`!error! ====> 【${e.message}】 getOwnPropertyDescriptor|obj:【${objName}】 (prop)——> 【${prop.toString()}】`); } return result; }, defineProperty: function (target, prop, descriptor) { let result; // 直接回调 try { result = Reflect.defineProperty(target, prop, descriptor); console.log(`defineProperty |obj:【${objName}】 (prop)——> 【${prop.toString()}】`); } catch (e) { console.log(`!error! ====> 【${e.message}】 defineProperty|obj:【${objName}】 (prop)——> 【${prop.toString()}】`); } return result }, apply: function (target, thisArgs, argumentList) { /* target : 函数对象 thisArgs: 调用函数的this指针 argumentList: 数组 列表 函数的入参组成的列表, 同JS中的apply方法。 */ let result; try { result = Reflect.apply(target, thisArgs, argumentList); let type = ld.getType(result) if (result instanceof Object) { console.log(`apply|function :【${objName}】 result:[${result}]`); } else if (typeof result === "symbol") { console.log(`apply|function :【${objName}】 result:[${result.toString()}]`); } else { console.log(`apply|function :【${objName}】, result:[${result}]`); } } catch (e) { console.log(`apply|function :【${objName}】 !error! ====> 【${e.message}】 `); } return result }, construct: function (target, argumentsList, newTarget) { /* target: 函数对象 argumentsList: 关键字传进来的参数 是一个列表 newTarget: 代理后的对象 */ let result; try { result = Reflect.construct(target, argumentsList, newTarget); let type = ld.getType(result); console.log(`construct|function :【${objName}】 type:[${type}]`); } catch (e) { console.log(`construct|function :【${objName}】 !error! ====> 【${e.message}】 `); } return result }, deleteProperty(target, propKey) { let result; result = Reflect.deleteProperty(target, propKey); console.log(`{deleteProperty|obj:[${objName}] ——> prop:[${propKey.toString()}], result:[${result}]}`); return result; }, has(target, propKey) { let result; result = Reflect.has(target, propKey); console.log(`{has|obj:[${objName}] ——> prop:[${propKey.toString()}], result:[${result}]}`); return result; }, ownKeys(target) { let result; result = Reflect.ownKeys(target); console.log(`{ownKeys|obj:[${objName}]}`) return result }, getPrototypeOf(target) { let result; result = Reflect.getPrototypeOf(target); console.log(`{getPrototypeOf|obj:[${objName}]`); return result; }, setPrototypeOf(target, proto) { let result; result = Reflect.setPrototypeOf(target, proto); console.log(`{setPrototypeOf|obj:[${objName}]`); return result; }, preventExtensions(target) { let result; result = Reflect.preventExtensions(target); console.log(`{preventExtensions|obj:[${objName}]}`) return result }, isExtensible(target) { let result; result = Reflect.isExtensible(target); console.log(`{isExtensible|obj:[${objName}]}`) return result } }; return new Proxy(obj, handler) }