You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
196 lines
8.6 KiB
196 lines
8.6 KiB
var proxies = {};
|
|
proxies.config = {};
|
|
proxies.config.start = true; // 是否启动拦截
|
|
proxies.config.get = true; // 是否拦截获取
|
|
proxies.config.set = true; // 是否拦截设置
|
|
proxies.config.apply = false; // 是否拦截函数执行
|
|
proxies.config.getOwnPropertyDescriptor = false; // 是否拦截获取自己的属性描述符
|
|
proxies.config.defineProperty = false; // 是否拦截定义属性
|
|
proxies.config.construct = false;
|
|
proxies.config.deleteProperty = false;
|
|
proxies.config.has = false;
|
|
proxies.config.ownKeys = false;
|
|
proxies.config.getPrototypeOf = false;
|
|
proxies.config.setPrototypeOf = false;
|
|
proxies.config.preventExtensions = false;
|
|
proxies.config.isExtensible = false;
|
|
proxies.config.index = 0
|
|
|
|
proxies.get_type = function (data) {
|
|
return Object.prototype.toString.call(data);
|
|
};
|
|
proxies.proxy = function proxy(obj, objName) {
|
|
//obj:原始对象
|
|
//objName:原始对象的名字
|
|
if (!proxies.config.start) {
|
|
console.log('代理已关闭');
|
|
return obj
|
|
}
|
|
let handler = {
|
|
get: function (target, prop, receiver) {//三个参数
|
|
//target: 原始对象 这里是user
|
|
//属性:属性 只有string和symbol两个类型
|
|
//receiver:代理后的对象 这里的proxyUser就是被代理后的对象
|
|
let result;
|
|
|
|
try {//防止出错
|
|
result = Reflect.get(target, prop, receiver);//和target[prop]是一样的 反射 执行原始操作
|
|
let type = proxies.get_type(result);
|
|
if (result instanceof Object) {
|
|
console.log(`${proxies.config.index}, 获取:[${objName}] -> 属性:[${prop.toString()}],type:[${type}]}`);
|
|
//递归调用
|
|
// result = proxies.proxy(result, `${objName}.${prop.toString()}`);//如果prop是Symbol类型${prop}会报错,这里toString是为了防止报错
|
|
} else if (typeof result === 'symbol') {
|
|
console.log(`${proxies.config.index}, 获取:[${objName}] -> 属性:[${prop.toString()}],结果:[${result.toString()}]}`);
|
|
} else {
|
|
console.log(`${proxies.config.index}, 获取:[${objName}] -> 属性:[${prop.toString()}],结果:[${result}]}`);// 这里使用${JSON.stringify(result)}输出可能会报错,如果result存在循环引用的话。
|
|
}
|
|
//throw new Error('测试error');
|
|
} catch (e) {
|
|
console.log(`${proxies.config.index}, 获取:[${objName}] -> 属性:[${prop.toString()}],error:[${e.message}]}`);
|
|
}
|
|
proxies.config.index += 1;
|
|
return result;
|
|
},
|
|
set: function (target, prop, value, receiver) {
|
|
let result;
|
|
try {
|
|
result = Reflect.set(target, prop, value, receiver);
|
|
let type = proxies.get_type(value);
|
|
if (value instanceof Object) {
|
|
console.log(`设置:[${objName}] -> 属性:[${prop.toString()}],type:[${type}]}`);
|
|
} else if (typeof value === 'symbol') {
|
|
console.log(`设置:[${objName}] -> 属性:[${prop.toString()}],value:[${value.toString()}]}`);
|
|
} else {
|
|
console.log(`设置:[${objName}] -> 属性:[${prop.toString()}],value:[${value}]}`);
|
|
}
|
|
} catch (e) {
|
|
console.log(`设置:[${objName}] -> 属性:[${prop.toString()}],error:[${e.message}]}`);
|
|
}
|
|
proxies.config.index += 1;
|
|
return result;
|
|
},
|
|
getOwnPropertyDescriptor: function (target, prop) {
|
|
let result;//结果两种 undefined和描述符对象
|
|
try {
|
|
result = Reflect.getOwnPropertyDescriptor(target, prop);
|
|
let type = proxies.get_type(result);
|
|
console.log(`getOwnPropertyDescriptor|obj:[${objName}] -> 属性:[${prop.toString()}],type:[${type}]}`);
|
|
|
|
//这里有需要再拦截,拦截的话会输出大量日志信息
|
|
//if(typeof result !== 'undefined'){
|
|
// result = ldvm.toolsFunc.proxy(result,`${objName}.${prop.toString()}.PropertyDescriptor`);
|
|
//}
|
|
} catch (e) {
|
|
console.log(`getOwnPropertyDescriptor|obj:[${objName}] -> 属性:[${prop.toString()}],error:[${e.message}]}`);
|
|
}
|
|
proxies.config.index += 1;
|
|
return result;
|
|
},
|
|
defineProperty: function (target, prop, descriptor) {
|
|
let result;
|
|
try {
|
|
result = Reflect.defineProperty(target, prop, descriptor);
|
|
console.log(`defineProperty|obj:[${objName}] -> 属性:[${prop.toString()}]}`);
|
|
} catch (e) {
|
|
console.log(`defineProperty|obj:[${objName}] -> 属性:[${prop.toString()}],error:[${e.message}]}`);
|
|
}
|
|
proxies.config.index += 1;
|
|
return result;
|
|
},
|
|
apply: function (target, thisArg, argumentsList) {
|
|
//target:函数对象
|
|
//thisArg:调用函数的this指针
|
|
//argumentsList:数组,函数的入参组长的一个列表
|
|
let result;
|
|
try {
|
|
result = Reflect.apply(target, thisArg, argumentsList);
|
|
let type = proxies.get_type(result);
|
|
if (result instanceof Object) {
|
|
console.log(`apply|function:[${objName}],type:[${result}]}`);
|
|
//一般不对函数返回的对象进行拦截,主要还是关注get函数拦截,针对浏览器接口,document,window这些
|
|
//特殊情况,可以对函数返回对象进行拦截
|
|
} 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}]}`);
|
|
}
|
|
proxies.config.index += 1;
|
|
return result;
|
|
},
|
|
construct: function (target, argArray, newTarget) {
|
|
//target:函数对象
|
|
//argArray:调用函数的this指针
|
|
//newTarget:代理对象
|
|
let result;
|
|
try {
|
|
result = Reflect.construct(target, argArray, newTarget);
|
|
let type = proxies.get_type(result);
|
|
console.log(`construct|function:[${objName}],type:[${type}]}`);
|
|
|
|
} catch (e) {
|
|
console.log(`construct|function:[${objName}],error:[${e.message}]}`);
|
|
}
|
|
proxies.config.index += 1;
|
|
return result;
|
|
},
|
|
deleteProperty: function (target, propKey) {
|
|
let result = Reflect.deleteProperty(target, propKey);
|
|
console.log(`deleteProperty|obj:[${objName}] -> 属性:[${propKey.toString()}],result:[${result}]}`);
|
|
proxies.config.index += 1;
|
|
return result;
|
|
},
|
|
has: function (target, propKey) {//in 操作符
|
|
let result = Reflect.has(target, propKey);
|
|
console.log(`has|obj:[${objName}] -> 属性:[${propKey.toString()}],result:[${result}]}`);
|
|
proxies.config.index += 1;
|
|
return result;
|
|
},
|
|
ownKeys: function (target) {//
|
|
let result = Reflect.ownKeys(target);
|
|
console.log(`ownKeys|obj:[${objName}]}`);
|
|
proxies.config.index += 1;
|
|
return result;
|
|
},
|
|
getPrototypeOf: function (target) {//
|
|
let result = Reflect.getPrototypeOf(target);
|
|
console.log(`getPrototypeOf|obj:[${objName}]}`);
|
|
proxies.config.index += 1;
|
|
return result;
|
|
},
|
|
setPrototypeOf: function (target, proto) {//
|
|
let result = Reflect.setPrototypeOf(target, proto);
|
|
console.log(`setPrototypeOf|obj:[${objName}]}`);
|
|
proxies.config.index += 1;
|
|
return result;
|
|
},
|
|
preventExtensions: function (target) {//
|
|
let result = Reflect.preventExtensions(target);
|
|
console.log(`preventExtensions|obj:[${objName}]}`);
|
|
proxies.config.index += 1;
|
|
return result;
|
|
},
|
|
isExtensible: function (target, proto) {//
|
|
let result = Reflect.isExtensible(target);
|
|
console.log(`isExtensible|obj:[${objName}]}`);
|
|
proxies.config.index += 1;
|
|
return result;
|
|
}
|
|
};
|
|
let config_keys = Object.keys(handler);
|
|
|
|
for (let i = 0; i < config_keys.length; i++) {
|
|
|
|
if (proxies.config[config_keys[i]] !== true) {
|
|
// console.log('不拦截:' + config_keys[i])
|
|
delete handler[config_keys[i]]
|
|
} else {
|
|
// console.log('开始拦截:' + config_keys[i])
|
|
}
|
|
}
|
|
return new Proxy(obj, handler);
|
|
}
|
|
module.exports.proxies = proxies;
|