首页 > 其他分享 >js代理函数

js代理函数

时间:2024-09-12 09:25:03浏览次数:12  
标签:function return 函数 代理 js toString result identifier arguments

const hook = true, compress = true

delete process
delete global
delete require
delete module
delete Buffer
delete __dirname
delete __file__

const hook_funcs = ['toString', 'hasOwnProperty']
const constructor_excepts = [Date, RegExp]

const $toString = Function.toString;
const myFunction_toString_symbol = Symbol('('.concat('', ')_', (Math.random() + '').toString(36)));
const myToString = function () {
    return typeof this == 'function' && this[myFunction_toString_symbol] || (result = $toString.call(this), compress ? result.replace(/\n/g, '').replace(/ /g, '') : result);
};

function set_native(func, key, value) {
    return Object.defineProperty(func, key, {
        "enumerable": false,
        "configurable": true,
        "writable": true,
        "value": value
    })
};
delete Function.prototype['toString'];
set_native(Function.prototype, "toString", myToString);
set_native(Function.prototype.toString, myFunction_toString_symbol, "function toString() { [native code] }");
function func_set_natvie(func) {
    return set_native(func, myFunction_toString_symbol, `function ${myFunction_toString_symbol, func.name || ''}() { [native code] }`);
}

let _origin_string_idx_of = String.prototype.indexOf
String.prototype.indexOf = function () {
    let result = _origin_string_idx_of.apply(this, arguments)
    console.log(`[string ${this}].indexOf`, arguments, result)
    return result
}
func_set_natvie(String.prototype.indexOf)

let _origin_regexp_test = RegExp.prototype.test
RegExp.prototype.test = function () {
    let result = _origin_regexp_test.apply(this, arguments)
    console.log(`[regexp ${this}].test`, arguments, result)
    return result
}
func_set_natvie(RegExp.prototype.test)

let _stringify_prototypes = []

function _stringify(e) {
    let ret = _stringify_prototypes.find(k => e instanceof k)
    return ret ? `[object ${ret.name}]` : e
}

function common_proxy(obj, opts = {}) {
    let {
        identifier,
        prototype,
        stringify,
        native
    } = opts
    if (native) {
        func_set_natvie(obj)
    }
    if (!hook) return obj
    let obj_type = typeof obj
    if (obj_type != "object" && obj_type != "function") return

    if (!identifier) {
        if (prototype) {
            identifier = prototype.name + '.prototype.' + obj.name
        } else {
            identifier = obj instanceof Function ? `[function ${obj.name}]` : obj.toString()
        }
    }
    if (!identifier.startsWith('[')) {
        identifier = `[` + identifier + ']'
    }
    if (stringify) {
        _stringify_prototypes.push(obj)
    }
    return new Proxy(obj, {
        construct() {
            let result = Reflect.construct.apply(this, arguments);
            console.log(`${identifier}.new => `, arguments, result);
            return constructor_excepts.find(e => result instanceof e) ? result : common_proxy(result)
        },
        apply() {
            try {
                let result = Reflect.apply.apply(this, arguments);
                console.log(`${identifier}.apply => `, _stringify(arguments[1]), arguments[2].map(e => _stringify(e)), result);
                return result
            } catch (e) {
                console.log(`${identifier}.apply => `, _stringify(arguments[1]), arguments[2].map(e => _stringify(e)), e.message);
                throw e
            }
        },
        // 代理这个对象的属性设置  a.b , a["b"]
        get: function () {
            let result = Reflect.get.apply(this, arguments)
            if (typeof arguments[1] == "string" && !arguments[1].startsWith("_")) {
                if (hook_funcs.includes(arguments[1])) {
                    result = common_proxy(result, {
                        identifier: identifier + `.` + arguments[1]
                    })
                }
                console.log(
                    `${identifier}.get => `, arguments[1], _stringify(result)
                )
            }
            return result
        },
        // 代理这个对象的属性设置  a.b = 1, a["b"]  1
        set: function () {
            let result = Reflect.set.apply(this, arguments)
            if (typeof arguments[1] == "string" && !arguments[1].startsWith("_")) {
                console.log(`${identifier}.set => `, arguments[1], _stringify(arguments[2]));
            }
            return result
        },
        // in 操作符的捕捉器  "xx" in a
        has: function () {
            let result = Reflect.has.apply(this, arguments)
            console.log(`${identifier}.has => `, arguments[1], result);
            return result
        },
        // Object.getOwnPropertyNames(a) 方法和 Object.getOwnPropertySymbols(a) 方法的捕捉器。
        ownKeys: function () {
            let result = Reflect.ownKeys.apply(this, arguments)
            console.log(`${identifier}.ownKeys => `, result.length);
            return result
        },
        // delete a.xxx
        deleteProperty: function () {
            let result = Reflect.deleteProperty.apply(this, arguments)
            console.log(`${identifier}.delete => `, arguments, result);
            return result
        },
    })
}

class Window {
    constructor() {}
    get[Symbol.toStringTag]() {
        return "Window"
    }
}

window = common_proxy(new Window)
window.Window = common_proxy(Window, {
    native: true,
    stringify: true
})

window.self = window.window = window;

标签:function,return,函数,代理,js,toString,result,identifier,arguments
From: https://www.cnblogs.com/thx2199/p/18409536

相关文章

  • lambda匿名函数使用场景举例
    lambda函数是Python中的一种简洁的匿名函数,常用于需要快速定义简单函数的场景。尽管lambda函数的功能较为有限(只能包含单个表达式),但它在很多情况下仍然非常有用。以下是一些常见的使用场景和示例:1.作为高阶函数的参数许多内置函数和库函数(如map()、filter()和sorted())......
  • 前端vue2 常用的函数
    1、在el-menu开启路由模式,default-active使用动态值等于当前路由,就需要用:default-active="$route.path" 2、阿里巴巴矢量图icfont的使用 ①将自己需要的图标下载到矢量库对应的项目文件中 ②更新对应的css代码,点击css代码链接,更新到本地去 ③使用<iclass="iconfont......
  • js简介
    js简介js出生的时候是为了解决表单数据的合法性验证JavaScript:简写js,但是他与Java没有半毛钱关系js可以控制web前端技术的钱两者:html(结构)和css(样式)js基础语法ctrl+?依旧是注释的快捷键,只不过在不同语言的语法显示不一样alert的作用是弹出对话框,小括号中的内容可以提示文字......
  • JsonConfigurationFileParser
    internalclassProgram{staticasyncTaskMain(string[]args){varroot=newRoot{Demo1=newDemo1{Name="Demo1",Data=newDemo2{Name="Demo2"......
  • JS获取URL参数的几种方法
    JS获取URL参数的几种方法在Web开发中,经常需要从URL中提取参数来进行相应的操作。本文将深度解析在JavaScript中获取URL参数的几种方法,并附带一些扩展与高级技巧。希望对你有所帮助!一、JS获取URL参数包含哪些方式1.使用URL对象现......
  • 函数递归的学习1
    了解递归递归是什么1.在C语言中,递归就是函数自己调用自己。递归的思想把⼀个大型复杂问题层层转化为⼀个与原问题相似,但规模较小的子问题来求解;直到子问题不能再被拆分,递归就结束了。所以递归的思考方式就是把大事化小的过程。递归中的递就是递推的意思,归就是回归的意思。......
  • fastjson1.2.24反序列化漏洞复现 CVE-2017-18349
    1.准备:1.1复现环境漏洞环境:vulnhub靶场工具准备:jdk8,apache-maven-3.9.9,kali2024.1,MarshalSec1.2环境启动进入vulnhub目录下的fastjson目录,进入CVE-2017-18349目录cd/home/hbesljx/vulhub/fastjson/1.2.24-rcedocker-compoe启动漏洞环境docker-composeup-d访问靶机......
  • Threejs之光线投射Raycaster
    本文目录前言一、简要介绍1.1定义与原理1.2构造器1.3常用属性1.4常用方法二、代码准备及效果2.1演示代码准备2.2效果三、创建射线Raycaster及效果3.1代码3.2效果四、完整代码前言Three.js中的光线投射(Raycaster)是一个功能强大的类,用于在三维场景中执行射......
  • Threejs之光线投射Raycaster交互
    这里写目录标题前言一、前置准备1.1代码1.2效果二、添加交互事件2.1代码2.2效果三、完整代码前言基于上篇文章Threejs之光线投射Raycaster我们知道了光线投射的基础用法,在本届我们将使用光线投射进行鼠标交互事件一、前置准备1.1代码<!DOCTYPEhtml><ht......
  • 【自用22.】C++类的静态数据成员以及静态成员函数
    需要获取总的人数,如何实现?方案一:使用全局变量,在构造函数中对这个全局变量进行修改具体代码如下:在Human.cpp中定义全局变量,并在构造函数中对人数进行增加操作#include"Human.h"#include<iostream>usingnamespacestd;intHumanCount=0;Human::Human(){ name......