用法:
// 定义传参的方法 方法名及形参需同步给U3D开发人员 returnUidToU3d(uid) { console.log('uid:' + uid); } /** * 通过hook 在执行returnUidToU3d时将调用window.HookEvent * window.HookEvent会在U3D那边被监听 从而实现前端传参给U3D */ returnUidToU3d.hook(window.HookEvent, this); // 伪代码 业务处理 businessHandle() { ... ... // 此时U3D将接收到传递的uid returnUidToU3d(uid); }
function Hooks() { return { initEnv: function () { // 在Function原型上增加hook方法 Function.prototype.hook = function (hookFunc, context) { var _context = null; //函数上下文 var _funcName = null; //函数名 _context = context || window; _funcName = getFuncName(this); _context['realFunc_' + _funcName] = this; if ( _context[_funcName].prototype && _context[_funcName].prototype.isHooked ) { console.log('Already has been hooked,unhook first'); return false; } function getFuncName(fn) { // 获取函数名 return fn.name.replace('bound ', ''); } try { eval( '_context[_funcName] = function ' + _funcName + '(){\n' + 'var args = [];\n' + "args.push(_context['realFunc_" + _funcName + "'].name.replace('bound ',''));\n" + 'args.push(Array.prototype.slice.call(arguments,0));\n' + 'var obj = this;\n' + 'hookFunc.apply(obj,args);\n' + "return _context['realFunc_" + _funcName + "'].apply(obj,args);\n" + '};' ); _context[_funcName].prototype.isHooked = true; return true; } catch (e) { console.log('Hook failed,check the params.'); return false; } }; // 在Function原型上增加unhook方法 Function.prototype.unhook = function (context) { var _context = null; var _funcName = null; _context = context || window; _funcName = this.name.replace('bound ', ''); if (!_context[_funcName].prototype.isHooked) { console.log('No function is hooked on'); return false; } _context[_funcName] = _context['realFunc' + _funcName]; delete _context['realFunc']; console.log('已释放' + _funcName); return true; }; }, }; } // 初始化hook var hook = Hooks(); hook.initEnv(); function HookEvent() { HookHandler(...arguments); }