proxy 收集

 

 

 

 

 

memory = {
    'Proxy': true,
    'random': 0.5,
}

// Math.random = function(){return memory['random']};

memory.proxy = (function() {
    memory.Object_sx = ['Date'];
    memory.Function_sx = []//['Array', 'Object', 'Function', 'String', 'Number', 'RegExp', 'Symbol', 'Error', 'EvalError', 'RangeError', 'ReferenceError', 'SyntaxError', 'TypeError', 'URIError', 'Uint8Array'];
    memory.setFun = [];
    memory.getObjFun = [];
    memory.color = {
        'set': [3, 101, 100],
        'get': [255, 140, 0],
        'has': [220, 87, 18],
        'apply': [107, 194, 53],
        'ownKeys': [147, 224, 255],
        'deleteProperty': [199, 21, 133],
        'defineProperty': [179, 214, 110],
        'construct': [200, 8, 82],
        'getPrototypeOf': [255, 255, 255],

        'object': [147, 224, 255],
        'function': [147, 224, 255],
        'number': [255, 224, 0],
        'array': [147, 224, 0],
        'string': [255, 224, 255],
        'undefined': [255, 52, 4],
        'boolean': [76, 180, 231],
    };
    memory.log = console.log;
    memory.log_order = 0;
    memory.proxy_Lock = 0;
    // 文本样式
    function styledText(text, styles) {
        let styledText = text;
        // RGB颜色
        if (styles.color) {
            styledText = `\x1b[38;2;${styles.color[0]};${styles.color[1]};${styles.color[2]}m${styledText}\x1b[0m`;
        }
        // 背景颜色
        if (styles.bgColor) {
            styledText = `\x1b[48;2;${styles.bgColor[0]};${styles.bgColor[1]};${styles.bgColor[2]}m${styledText}\x1b[0m`;
        }
        // 粗体
        if (styles.bold) {
            styledText = `\x1b[1m${styledText}\x1b[0m`;
        }
        // 斜体
        if (styles.italic) {
            styledText = `\x1b[3m${styledText}\x1b[0m`;
        }
        // 下划线
        if (styles.underline) {
            styledText = `\x1b[4m${styledText}\x1b[0m`;
        }
        // 返回带样式的文本
        return styledText
    }
    // 文本填充
    function limitStringTo(str, num) {
        str = str.toString()
        if (str.length >= num) {
            return str + ' '
        } else {
            const spacesToAdd = num - str.length;
            const padding = ' '.repeat(spacesToAdd);
            // 创建填充空格的字符串
            return str + padding;
        }
    }
    // 进行代理
    function new_obj_handel(target, target_name) {
        if(memory.Proxy == false){return target};

        let name = target_name.indexOf('.') != -1 ? target_name.split('.').slice(-1)[0]: target_name;
        if (target['isProxy'] || memory.Object_sx.includes(name)) {
            return target;
        }else{
            return new Proxy(target,my_obj_handler(target_name))
        }
    }
    function new_fun_handel(target, target_name) {
        if(memory.Proxy == false){return target}
        let name = target_name.indexOf('.') != -1 ? target_name.split('.').slice(-1)[0]: target_name;
        if (memory.Function_sx.includes(name)) {
            return target;
        }else{
            return new Proxy(target,my_fun_handler(target_name))
        }
    }
    // 获取数据类型
    function get_value_type(value) {
        if (Array.isArray(value)) {
            return 'array'
        }
        if (value == undefined) {
            return 'undefined'
        }
        return typeof value;
    }
    // 函数与对象的代理属性
    function my_obj_handler(target_name) {
        return {
            set: function (obj, prop, value) {
                if(memory['proxy_Lock']){
                    return Reflect.set(obj, prop, value);
                };

                const value_type = get_value_type(value);
                const tg_name = `${target_name}.${prop.toString()}`;
                const text = limitStringTo(++memory['log_order'],5) + limitStringTo('setter',20) + limitStringTo(`hook->${tg_name};`,50)

                // 如果设置到的属性是对象 --> 输出值对象
                // 如果设置到的属性是方法 --> 输出值function
                // 其他的就全部输出值
                if (value && value_type === "object") {
                    memory.log(styledText(text, {
                        color: memory.color['set'],
                    }), styledText('value->',{
                        color: memory.color['set'],
                    }),value)
                }
                else if (value_type === "function") {
                    memory.setFun.push(tg_name)
                    memory.log(styledText(text , {
                        color: memory.color['set'],
                    }),styledText(`value->`, {
                        color: memory.color['set'],
                    }),styledText(`function`, {
                        color: memory.color[value_type],
                    }))
                }
                else {
                    memory.log(styledText(text, {
                        color: memory.color['set'],
                    }),styledText(`value->`, {
                        color: memory.color['set'],
                    }),styledText(`${value}`, {
                        color: memory.color[value_type],
                    }))
                }

                return Reflect.set(obj, prop, value);
            },
            get: function (obj, prop) {
                if(memory['proxy_Lock']){
                    return Reflect.get(obj, prop)
                };
                if (prop === "isProxy") {
                    return true;
                }

                const value = Reflect.get(obj, prop);
                const tg_name = `${target_name}.${prop.toString()}`;
                const value_type = get_value_type(value);

                const text = limitStringTo(++memory['log_order'],5) + limitStringTo('getter',20) + limitStringTo(`hook->${tg_name};`,50)
                // 如果获取到的属性是对象 --> 对其getter和setter进行代理
                // 如果获取到的属性是方法 --> 对其caller进行代理
                // 其他的就全部输出值
                if (value_type === 'object') {
                    if (memory.getObjFun.indexOf(tg_name) == -1){
                        memory.log(styledText(text, {
                            color: memory.color['get'],
                        }), styledText('value->',{
                            color: memory.color['get'],
                        }),value)
                        memory.getObjFun.push(tg_name)
                    }
                    return new_obj_handel(value,tg_name)
                }
                else if(value_type === "function"){
                    if (memory.getObjFun.indexOf(tg_name) == -1){
                        memory.log(styledText(text , {
                            color: memory.color['get'],
                        }),styledText(`value->`, {
                            color: memory.color['get'],
                        }),styledText(`function`, {
                            color: memory.color[value_type],
                        }))
                        memory.getObjFun.push(tg_name)
                    }
                    return new_fun_handel(value,tg_name);
                }
                else{
                    memory.log(styledText(text , {
                            color: memory.color['get'],
                        }),styledText( `value->` , {
                            color: memory.color['get'],
                        }),styledText( `${value}` , {
                            color: memory.color[value_type],
                        }))
                    return value
                }
            },
            has: function(obj, prop) {
                if(memory['proxy_Lock']){
                    return Reflect.has(obj, prop)
                }

                const value = Reflect.has(obj, prop);
                const value_type = get_value_type(value);
                const text = limitStringTo(++memory['log_order'],5) + limitStringTo('in',20) + limitStringTo(`hook->"${prop.toString()}" in ${target_name};`,50)
                memory.log(styledText(text, {
                        color: memory.color['has'],
                    }), styledText(`value->`, {
                        color: memory.color['has'],
                    }), styledText(`${value}`, {
                        color: memory.color[value_type],
                    }))

                return value;
            },
            ownKeys:function(obj){
                if(memory['proxy_Lock']){
                    return Reflect.ownKeys(obj);
                }

                const value = Reflect.ownKeys(obj);
                const value_type = get_value_type(value);
                const text = limitStringTo(++memory['log_order'],5) + limitStringTo('ownKeys',20) + limitStringTo(`hook->${target_name};`,50)
                memory.log(styledText(text, {
                        color: memory.color['ownKeys'],
                    }), styledText(`value->`, {
                        color: memory.color['ownKeys'],
                    }), styledText(`${value}`, {
                        color: memory.color[value_type],
                    }));

                return value
            },
            deleteProperty:function(obj, prop) {
                if(memory['proxy_Lock']){
                    return Reflect.deleteProperty(obj, prop);
                }

                const value = Reflect.deleteProperty(obj, prop);
                const tg_name = `${target_name}.${prop.toString()}`;
                const value_type = get_value_type(value);
                const text = limitStringTo(++memory['log_order'],5) + limitStringTo('delete',20) + limitStringTo(`hook->${tg_name};`,50)
                memory.log(styledText(text, {
                        color: memory.color['deleteProperty'],
                    }), styledText(`value->`, {
                        color: memory.color['deleteProperty'],
                    }), styledText(`${value}`, {
                        color: memory.color[value_type],
                    }));

                return value;
            },
            defineProperty: function (target, property, descriptor) {
                if(memory['proxy_Lock']){
                    return Reflect.defineProperty(target, property, descriptor);
                };

                const value = Reflect.defineProperty(target, property, descriptor);
                const tg_name = `${target_name}.${property.toString()}`;
                const text = limitStringTo(++memory['log_order'],5) + limitStringTo('defineProperty',20) + limitStringTo(`hook->${tg_name};`,50)
                memory.log(styledText(text, {
                        color: memory.color['defineProperty'],
                    }), styledText('value->',{
                        color: memory.color['defineProperty'],
                    }),descriptor)

                return value;
            },
            getPrototypeOf(target) {
                if(memory['proxy_Lock']){
                    return Reflect.getPrototypeOf(target);
                }

                var value = Reflect.getPrototypeOf(target);
                const text = limitStringTo(++memory['log_order'],5) + limitStringTo('getPrototypeOf',20) + limitStringTo(`hook->${target_name};`,50)
                memory.log(styledText(text, {
                        color: memory.color['getPrototypeOf'],
                    }), styledText('value->',{
                        color: memory.color['getPrototypeOf'],
                    }),value)

                return value;
            }
        };
    }
    function my_fun_handler(target_name) {
        return  {
            apply:function(target, thisArg, argumentsList){
                if(memory['proxy_Lock']){
                    return Reflect.apply(target, thisArg, argumentsList);
                };

               if(memory.setFun.indexOf(target_name) != -1 || memory.setFun.includes(target_name.split('.')[0])){
                    // 扣的代码触发
                    var value = Reflect.apply(target, thisArg, argumentsList);
                    memory.setFun.push(`log_${memory['log_order'] + 1}`)
                }
                else{
                    // 补的环境触发的分支
                    memory['proxy_Lock'] = 1
                    var value = Reflect.apply(target, thisArg, argumentsList);
                    memory['proxy_Lock'] = 0

                }

                const value_type = get_value_type(value);
                const text = limitStringTo(++memory['log_order'],5) + limitStringTo('caller',20) + limitStringTo(`hook->log_${memory['log_order']} = ${target_name}();`,50);
                memory.log(styledText(text, {
                        color: memory.color['apply'],
                    }),styledText('arguments->',{
                        color: memory.color['apply'],
                    }),argumentsList, styledText('returnValue->',{
                        color: memory.color[value_type],
                    }),value)

                if(value_type == 'object'){
                    return new_obj_handel(value,`log_${memory['log_order']}`);
                }
                else if(value_type == 'function'){
                    return new_fun_handel(value,`log_${memory['log_order']}`);
                }
                return  value;
            },
            construct: function (target, args, newTarget) {
                if(memory['proxy_Lock']){
                    return Reflect.construct(target, args, newTarget)
                }

                if(memory.setFun.indexOf(target_name) != -1 || memory.setFun.includes(target_name.split('.')[0])){
                    var value = Reflect.construct(target, args, newTarget);
                    memory.setFun.push(`log_${memory['log_order'] + 1}`)
                }
                else{
                    memory['proxy_Lock'] = 1
                    var value = Reflect.construct(target, args, newTarget);
                    memory['proxy_Lock'] = 0
                }


                const text = limitStringTo(++memory['log_order'],5) + limitStringTo('new',20) + limitStringTo(`hook->log_${memory['log_order']} = new ${target_name}();`,50)
                memory.log(styledText(text, {
                        color: memory.color['construct'],
                    }), styledText('arguments->',{
                        color: memory.color['construct'],
                    }),args, styledText('returnValue->',{
                        color: memory.color['construct'],
                    }),value);
                return new_obj_handel(value,  `log_${memory['log_order']}`);
            },
        }
    }
    // 返回进行对象代理
    return new_obj_handel
}());

 

 

 

 

 

 

 

 


 

 

 

dtavm = {}
dtavm.log = console.log
function proxy(obj, objname, type) {
    function getMethodHandler(WatchName, target_obj) {
        let methodhandler = {
            apply(target, thisArg, argArray) {
                if (this.target_obj) {
                    thisArg = this.target_obj
                }
                let result = Reflect.apply(target, thisArg, argArray)
                if (target.name !== "toString") {
                    if (target.name === "addEventListener") {
                        dtavm.log(`调用者 => [${WatchName}] 函数名 => [${target.name}], 传参 => [${argArray[0]}], 结果 => [${result}].`)
                    } else if (WatchName === "window.console") {
                    } else {
                        dtavm.log(`调用者 => [${WatchName}] 函数名 => [${target.name}], 传参 => [${argArray}], 结果 => [${result}].`)
                    }
                } else {
                    dtavm.log(`调用者 => [${WatchName}] 函数名 => [${target.name}], 传参 => [${argArray}], 结果 => [${result}].`)
                }
                return result
            },
            construct(target, argArray, newTarget) {
                var result = Reflect.construct(target, argArray, newTarget)
                dtavm.log(`调用者 => [${WatchName}] 构造函数名 => [${target.name}], 传参 => [${argArray}], 结果 => [${(result)}].`)
                return result;
            }
        }
        methodhandler.target_obj = target_obj
        return methodhandler
    }

    function getObjhandler(WatchName) {
        let handler = {
            get(target, propKey, receiver) {
                let result = target[propKey]
                if (result instanceof Object) {
                    if (typeof result === "function") {
                        dtavm.log(`调用者 => [${WatchName}] 获取属性名 => [${propKey}] , 是个函数`)
                        return new Proxy(result, getMethodHandler(WatchName, target))
                    } else {
                        dtavm.log(`调用者 => [${WatchName}] 获取属性名 => [${propKey}], 结果 => [${(result)}]`);
                    }
                    return new Proxy(result, getObjhandler(`${WatchName}.${propKey}`))
                }
                if (typeof (propKey) !== "symbol") {
                    dtavm.log(`调用者 => [${WatchName}] 获取属性名 => [${propKey?.description ?? propKey}], 结果 => [${result}]`);
                }
                return result;
            },
            set(target, propKey, value, receiver) {
                if (value instanceof Object) {
                    dtavm.log(`调用者 => [${WatchName}] 设置属性名 => [${propKey}], 值为 => [${(value)}]`);
                } else {
                    dtavm.log(`调用者 => [${WatchName}] 设置属性名 => [${propKey}], 值为 => [${value}]`);
                }
                return Reflect.set(target, propKey, value, receiver);
            },
            has(target, propKey) {
                var result = Reflect.has(target, propKey);
                dtavm.log(`针对in操作符的代理has=> [${WatchName}] 有无属性名 => [${propKey}], 结果 => [${result}]`)
                return result;
            },
            deleteProperty(target, propKey) {
                var result = Reflect.deleteProperty(target, propKey);
                dtavm.log(`拦截属性delete => [${WatchName}] 删除属性名 => [${propKey}], 结果 => [${result}]`)
                return result;
            },
            defineProperty(target, propKey, attributes) {
                var result = Reflect.defineProperty(target, propKey, attributes);
                dtavm.log(`拦截对象define操作 => [${WatchName}] 待检索属性名 => [${propKey.toString()}] 属性描述 => [${(attributes)}], 结果 => [${result}]`)
                // debugger
                return result
            },
            getPrototypeOf(target) {
                var result = Reflect.getPrototypeOf(target)
                dtavm.log(`被代理的目标对象 => [${WatchName}] 代理结果 => [${(result)}]`)
                return result;
            },
            setPrototypeOf(target, proto) {
                dtavm.log(`被拦截的目标对象 => [${WatchName}] 对象新原型==> [${(proto)}]`)
                return Reflect.setPrototypeOf(target, proto);
            },
            preventExtensions(target) {
                dtavm.log(`方法用于设置preventExtensions => [${WatchName}] 防止扩展`)
                return Reflect.preventExtensions(target);
            },
            isExtensible(target) {
                var result = Reflect.isExtensible(target)
                dtavm.log(`拦截对对象的isExtensible() => [${WatchName}] isExtensible, 返回值==> [${result}]`)
                return result;
            },
        }
        return handler;
    }

    if (type === "method") {
        return new Proxy(obj, getMethodHandler(objname, obj));
    }
    return new Proxy(obj, getObjhandler(objname));
}

 

 

 

 


 

 

window.luan_text = "";
window.luan_open = false;
function luan_proxy(arr, name) {
  // arr 内存
  // name 名字

  // 获取数据类型
  function get_value_type(value) {
    // 'undefined', 'null', 'boolean', 'string', 'number', 'symbol', 'array', 'object', 'function'
    if (Array.isArray(value)) {
      return "array";
    }
    if (value == null) {
      return "null";
    }
    return typeof value;
  }
  // 打印函数
  function luan_print(obj) {
    let type = get_value_type(obj);
    if (["undefined", "null", "boolean", "string", "number"].includes(type)) {
      return obj;
    } else if (obj[Symbol.toStringTag]) {
      return obj[Symbol.toStringTag];
    } else if (type == "function") {
      return `function ${obj.name}`;
    } else if (type == "object" || type == "array") {
      // JSON.stringify 会递归处理
      let temp = JSON.stringify(obj, function (k, v) {
        if (v && v[Symbol.toStringTag]) {
          return v[Symbol.toStringTag];
        } else if (v && typeof v == "function") {
          return `function ${v.name}`;
        } else {
          return v;
        }
      });
      return temp;
    } else if (type == "symbol") {
      return obj.toString();
    } else {
      // 未预料到的情况
      debugger;
    }
  }

  // 句柄
  let handle = {
    get(target, property, receiver) {
      let result;
      result = Reflect.get(target, property, receiver);
      try {
        if (window.luan_open) {
          let content = luan_print(target);
          window.luan_text += `${name}|get| 下标: ${property.toString()} 内容: ${content}\r\n`;
        }
      } catch (e) {
        debugger;
      }
      return result;
    },
    set(target, property, value, receiver) {
      let result;
      result = Reflect.set(target, property, value, receiver);
      try {
        if (window.luan_open) {
          let content = luan_print(target);
          window.luan_text += `${name}|set| 下标: ${property.toString()} 内容: ${content}\r\n`;
        }
      } catch (e) {
        debugger;
      }
      return result;
    },
  };
  return new Proxy(arr, handle);
} //………………
p = luan_proxy(p, "p1");

 

posted @ 2024-06-20 12:13  AngDH  阅读(3)  评论(0编辑  收藏  举报