

或者说,如何克隆一个函数的参数列表及函数体到一个新函数中?
举个例子,假如有个这样的Function.prototype.clone方法,它用于克隆函数,用法如下:
var original = function original_name(a, b) { return a + b; };
var cloned = original.clone();
alert(cloned == original); //false新函数是一个完完全全的新对象,它拥有自己的作用域,但用法却和原函数一模一样。
首先,你肯定会想到用eval,eval可以说是神通广大的一个魔鬼。
只需要短短几行代码,便可以实现这个需求:
Function.prototype.clone = function(){
var func;
eval("func = " + this.toString());
return func;
};既然eval能行得通,那么它的兄弟Function肯定也能做到:
Function.prototype.clone = function(){
return new Function("return " + this.toString())();
};这行代码甚至更加精辟,但是Function换一种用法,也未尝不是一种新解法:
String.prototype.trim = function(){
return this.replace(/(^\s*)|(\s*$)/g, "");
};
Function.prototype.clone = function() {
var findArgs = function(funcStr){
var bracket1 = funcStr.indexOf("(");
var bracket2 = funcStr.indexOf(")");
var argsStr = funcStr.slice(bracket1+1,bracket2);
var args = argsStr.split(",");
return args.map(function(e){
return e.trim();
});
};
var funcStr = this.toString();
var args = findArgs(funcStr);
var bigBracket1 = funcStr.indexOf("{");
var bigBracket2 = funcStr.lastIndexOf("}");
var body = funcStr.slice(bigBracket1+1,bigBracket2);
args.push(body);
return Function.apply(null,args);
};这种写法利用了Function函数的特性,先获得原函数的字符串,截取参数列表,函数体的字符串,依次注入Function调用。
这个截取过程可以用正则来写,使代码更加简洁。
