用法:
// 定义传参的方法 方法名及形参需同步给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);
}