views:

92

answers:

2

What is a fastest way to clone a function in JavaScript (with or without its properties)?

Two options coming to mind are eval(func.toString()) and function() { return func.apply(..) }. But I am worried about performance of eval and wrapping will make stack worse and will probably degrade performance if applied a lot or applied to already wrapped.

new Function(args, body) looks nice, but how exactly can I reliable split existing function to args and body without a JS parser in JS?

Thanks in advance.

Update: What I mean is being able to do

var funcB = funcA.clone(); // where clone() is my extension
funcB.newField = {...};    // without affecting funcA
A: 

Just wondering - why would you want to clone a function when you have prototypes AND can set the scope of a function call to anything you wish?

 var funcA = {};
 funcA.data = 'something';
 funcA.changeData = function(d){ this.data = d; }

 var funcB = {};
 funcB.data = 'else';

 funcA.changeData.call(funcB.data);

 alert(funcA.data + ' ' + funcB.data);
Upper Stage
If there is a reason to change fields of function itself (self-contained cache, 'static' properties), then there are situation when I want to clone a function and modify it without affecting the original one.
Andrey Shchekin
I mean the properties of function itself.
Andrey Shchekin
Then, I like Jared's answer.
Upper Stage
+2  A: 

try this:

var x = function() {
    return 1;
};

var t = function(a,b,c) {
    return a+b+c;
};


Function.prototype.clone = function() {
    var that = this;
    var temp = function temporary() { return that.apply(this, arguments); };
    for( key in this ) {
        temp[key] = this[key];
    }
    return temp;
};

alert(x === x.clone());
alert(x() === x.clone()());

alert(t === t.clone());
alert(t(1,1,1) === t.clone()(1,1,1));
alert(t.clone()(1,1,1));
Jared
Ok, so apply is the only way? I would improve on this a bit so that it does not wrap twice when called twice, but otherwise, ok.
Andrey Shchekin
apply is used to pass the arguments easily. also, this will work for instances where you want to clone a constructor.
Jared
yes, I wrote about apply in the original post. problem is that wrapping function like this destroys its name and will slow down after many clones.
Andrey Shchekin