克隆JavaScript函数:除了使用eval还有什么比这更好的了吗?

时间:2011-05-26 08:17:01

标签: javascript oop

EDITED

注意:我已经完全编辑了这个,因为之前的问题是通过另一种方法解决的,我已经简化了这个问题,以便回答我自己的问题解决方案并与你分享我的结论。

如何通过避免使用eval(...)来克隆函数?

我需要获得某个给定函数的精确副本,这必须是与源代码不同的对象。

那是functionA != functionCloneOfA,包装“functionA”并从其他人的身体调用它对我来说不是一个解决方案。

3 个答案:

答案 0 :(得分:2)

您是否考虑过Lasse Reichstein Nielsen的“克隆”功能?本质上,它通过返回一个在其原型链上具有该功能的新对象来“克隆”一个函数。 Douglas Crockford称他的版本为"beget"

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

var myClone = cloneFn(someFn);

返回[[prototype]]为“克隆”someFn函数的对象。

答案 1 :(得分:1)

我想我现在得到你需要的东西。你需要的只是在B对象上调用A的构造函数,如下所示:

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);

如果您不想这样做,可以像这样从B内部调用A构造函数:

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

但是您需要手动将所有原型函数从A复制到B。

答案 2 :(得分:0)

最后我不需要克隆函数来解决我的一个项目中的一些问题,但是我想与你分享我为了真正克隆一个函数所发现的东西:

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

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

我并不完全确定这是最好的方法,但它会产生一个匿名函数,它是源函数的精确克隆,但两者都是不同的对象。

也许使用某种“eval”因为我正在使用这个Function对象构造函数构建一个函数,但我相信它比实际使用 eval(...)更优雅。