如果您需要支持具有任意数量参数的函数,您只需要走eval
/路线。Function
如果您可以设置合理的上限(我的示例是 5),那么您可以执行以下操作:
var wrapFunction = function( func, code, where ){
var f;
switch ( where ) {
case 'after':
f = function(t,a,r){ r = func.apply(t,a); code.apply(t,a); return r; }
break;
case 'around':
f = function(t,a){ return code.call(t,func,a); }
break;
default:
case 'before':
f = function(t,a){ code.apply(t,a); return func.apply(t,a); }
break;
}
switch ( func.length ) {
case 0: return function(){return f(this, arguments);}; break;
case 1: return function(a){return f(this, arguments);}; break;
case 2: return function(a,b){return f(this, arguments);}; break;
case 3: return function(a,b,c){return f(this, arguments);}; break;
case 4: return function(a,b,c,d){return f(this, arguments);}; break;
case 5: return function(a,b,c,d,e){return f(this, arguments);}; break;
default:
console.warn('Too many arguments to wrap successfully.');
break;
}
}
这种包装代码的方法也可以通过创建不同的where
开关来扩展。我已经实现了before
,after
因为它们对我自己的项目最有用——而且around
只是因为它让我想起了 lisp。使用此设置,您还可以将包装 ( var f
) 移交给外部代码,从而允许您为where
关键字开发类似系统的插件,这意味着您可以轻松扩展或覆盖所wrapFunction
支持的内容。
显然,您可以随意更改代码的实际包装方式,关键在于使用与 999 和 AdrianLang 类似的技术,而无需担心构建字符串和传递给new Function
.