JavaScript: clone a function
Here is an updated answer
var newFunc = oldFunc.bind({}); //clones the function with '{}' acting as its new 'this' parameter
However .bind
is a modern ( >=iE9 ) feature of JavaScript (with a compatibility workaround from MDN)
Notes
It does not clone the function object additional attached properties, including the prototype property. Credit to @jchook
The new function
this
variable is stuck with the argument given onbind()
, even on new functionapply()
calls. Credit to @Kevin
function oldFunc() {
console.log(this.msg);
}
var newFunc = oldFunc.bind({ msg: "You shall not pass!" }); // this object is binded
newFunc.apply({ msg: "hello world" }); //logs "You shall not pass!" instead
- Bound function object,
instanceof
treatsnewFunc
/oldFunc
as the same. Credit to @Christopher
(new newFunc()) instanceof oldFunc; //gives true
(new oldFunc()) instanceof newFunc; //gives true as well
newFunc == oldFunc; //gives false however
Here's a slightly better version of Jared's answer. This one won't end up with deeply nested functions the more you clone. It always calls the original.
Function.prototype.clone = function() {
var cloneObj = this;
if(this.__isClone) {
cloneObj = this.__clonedFrom;
}
var temp = function() { return cloneObj.apply(this, arguments); };
for(var key in this) {
temp[key] = this[key];
}
temp.__isClone = true;
temp.__clonedFrom = cloneObj;
return temp;
};
Also, in response to the updated answer given by pico.creator, it is worth noting that the bind()
function added in Javascript 1.8.5 has the same problem as Jared's answer - it will keep nesting causing slower and slower functions each time it is used.
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(var key in this) {
if (this.hasOwnProperty(key)) {
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));