开发者

Cloning a JavaScript function: anything else better than using eval?

EDITED

Note: I开发者_Go百科've completely edited this because previous problem was solved using another approach and I've simplified this question in order to answer myself with my solution to the question and share my conclusion with you.

How to clone a function by avoiding the use of eval(...)?

I need to get an exact copy of some given function and this must be a different object than source one.

That's functionA != functionCloneOfA, and wrapping "functionA" and calling it from the body of some other isn't a solution for me.


Have you considered Lasse Reichstein Nielsen's "clone" function? Essentially it "clones" a function by returning a new object that has the function on it's prototype chain. Douglas Crockford calls his version "beget".

var cloneFn = (function() {
    var F = function(){};
    return function(fn) {
        F.prototype = fn;
        return new F();
    }
}());

var myClone = cloneFn(someFn);

Returns an object whose [[prototype]] is the "cloned" someFn function.


I think I get what you need now. What you need is simply to call the A's constructor on the B-object, like this:

function A() { this._someVal = 'test'; }
function B() { this._someOtherVal = 'test2'; }
B.prototype = new A(); // this is how inheritance is normally done in Javascript.
B.prototype.getVal = function() { return this._someVal; }

var b = new B();
alert(b.getVal());
alert(b._someVal);
alert(b._someOtherVal);

If you don't want to do it that way, you can call the A-constructor from inside B like this:

function B() { A.call(this, []); this._someOtherVal = 'test2'; }

but than you need to manually copy all the prototype-functions from A to B.


Finally I didn't need to clone functions to solve some problem in one of my projects, but I want to share with you what I found in order to truly clone a function:

function cloneFunc(someFunc) {
    var someFuncAsText = someFunc.toString();

    return new Function
    (
        /\(([\s\S]*?)\)/.exec(someFunc)[1],
        someFuncAsText.substring(someFuncAsText.indexOf("{") + 1, someFuncAsText.lastIndexOf("}"))
    );
}

I'm not absolutely sure this is the best approach around, but it produces an anonymous function which is an exact clone of source function, but both are different objects.

Perhaps uses some kind of "eval" because I'm building a function by using this Function object constructor, but I believe it's more elegant than an actual use of eval(...).

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜