在javascript中,如何对一个函数进行克隆?
或者说,如何克隆一个函数的参数列表及函数体到一个新函数中?
举个例子,假如有个这样的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调用。
这个截取过程可以用正则来写,使代码更加简洁。
以上就是javascript趣题:函数克隆的内容。