如何在JavaScript中检测函数创建并在函数运行时触发代码
关于函数创建检测与运行时注入的问题
一、重写Function构造函数的可行性
你提供的代码无法实现检测所有函数创建,核心问题有两个:
Function.constructor本质就是Function自身,重写这个属性不会改变函数的创建逻辑;function asdf() {}这种声明式创建函数的方式,根本不会经过new Function()的构造流程,只有显式调用new Function()时才会触发你的alert,声明式函数完全不受影响。
如果要拦截通过new Function()创建的函数,正确的写法是重写Function本身:
const originalFunction = Function; Function = function(...args) { alert('通过new Function创建了新函数!'); return new originalFunction(...args); }; // 这个会触发alert const k = new Function(); // 但function声明依然不会触发 function asdf() {}
但要明确:这种方式只能拦截new Function()或Function()创建的函数,箭头函数、声明式函数这类语法层面生成的函数,不会走Function构造函数,所以无法被拦截。
二、获取当前所有已定义的函数
只能获取全局作用域下的函数,局部作用域的私有函数没有公开API可以直接遍历。全局函数的获取方式如下:
function getAllGlobalFunctions() { const functions = []; const globalObj = typeof window !== 'undefined' ? window : global; for (const key in globalObj) { try { const value = globalObj[key]; if (typeof value === 'function') { functions.push({ name: key, func: value }); } } catch (e) { // 跳过浏览器或Node.js中无法访问的内置属性 continue; } } return functions; } // 使用示例 const globalFuncs = getAllGlobalFunctions(); console.log(globalFuncs);
三、让每个函数运行时触发代码
核心思路是用包装函数替换原函数,先执行你的逻辑再调用原函数:
1. 包装已存在的全局函数
function wrapFunction(func, hook) { return function(...args) { // 先执行你的钩子代码 hook(func.name); // 调用原函数并返回结果 return func.apply(this, args); }; } // 示例钩子:打印函数执行信息 function functionRunHook(funcName) { console.log(`函数「${funcName}」开始执行`); } // 遍历全局对象,包装所有函数 const globalObj = typeof window !== 'undefined' ? window : global; for (const key in globalObj) { if (typeof globalObj[key] === 'function' && !globalObj[key].__wrapped) { globalObj[key] = wrapFunction(globalObj[key], functionRunHook); globalObj[key].__wrapped = true; // 标记已包装,避免重复处理 } } // 测试:调用alert会触发钩子 alert('测试');
2. 拦截未来创建的函数
普通JS环境下很难覆盖所有场景(比如声明式函数、箭头函数),因为这些是引擎直接解析生成的,不走构造函数流程。如果是Node.js环境可以借助VM模块,浏览器环境则需要依赖DevTools协议这类非常规手段,常规JS语法无法实现完全拦截。
内容的提问来源于stack exchange,提问作者cs6413110
相关产品推荐
相关产品推荐

