JavaScript趣题:函数克隆
程序员文章站
2022-03-31 16:17:32
...
在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趣题:函数克隆的内容,更多相关内容请关注PHP中文网(www.php.cn)!