Вам нужно идти по маршруту 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
, потому что они наиболее полезны для моего собственного проекта & mdash; и around
только потому, что это напоминает мне о лиспе. Используя эту настройку, вы также можете передать перенос (var f
) на внешний код, что позволит вам разработать систему, подобную плагину, для ключевых слов where
, что означает, что вы можете легко расширять или переопределять то, что поддерживает wrapFunction
.
Очевидно, вы можете изменить способ, которым код фактически обернут, как вам угодно, ключ на самом деле просто использует технику, аналогичную 999 и AdrianLang, просто не беспокоясь о построении строк и переходе на new Function
.