构造函数调用的快捷方式

时间:2012-04-06 13:15:49

标签: javascript

下面是我的 App 的简化版本,以下代码按预期工作。我可以在控制台中看到4个日志,其中包含我传递给SayHello的参数。

var App = {};

(function(that){

    that.SayHello = function(){
        console.log( arguments );
        return {
            doSomething: function(){
                console.log('done');
            }
        };
    };

    var obj = {
        t: new that.SayHello( 'a', 1 ),
        r: new that.SayHello( 'b', 2 ),
        b: new that.SayHello( 'c', 3 ),
        l: new that.SayHello( 'd', 4 )
    };

}(App));

问题:我正在尝试创建new that.SayHello的“快捷方式”,如下所示:

var Greet = function(){
        return new that.SayHello;
    },
    obj = {
        t: Greet( 'a', 1 ),
        r: Greet( 'b', 2 ),
        b: Greet( 'c', 3 ),
        l: Greet( 'd', 4 )
    };

控制台记录4个空数组。这意味着arguments未能通过。

我还尝试了return new that.SayHello.apply(this, arguments);return new that.SayHello.call(this, arguments);

如何将所有Greet arguments that.SayHello传递给that.SayHello
知道我必须使用new that.SayHello初始化arguments,否则我的代码会中断。

我正在为任意数量的arguments寻找一般解决方案,我不想逐一传递{{1}}。

此代码也可在jsfiddle上找到。

1 个答案:

答案 0 :(得分:1)

这样的东西?

var Greet = function(){
    var result = that.SayHello.prototype;
    that.SayHello.apply(result, arguments);
    return result;
}

您应该知道applyarguments应用于对象result。将result预定义为SayHello原型将为您提供所需内容。

修改

不幸的是,上面的代码将改变SayHello的原型。这显然是不需要的行为,所以为了避免这种情况,我认为我们应该复制原型对象。例如,使用以下代码

function clone(obj) {
    if (null == obj || "object" != typeof obj) return obj;
    var copy = obj.constructor();
    for (var attr in obj) {
        if (obj.hasOwnProperty(attr)) copy[attr] = obj[attr];
    }
    return copy;
}

var Greet = function(){
    var result = clone(that.SayHello.prototype);
    that.SayHello.apply(result, arguments);
    return result;
}

我在this answer中找到了这个clone函数的简单版本。它有很多问题,你应该检查其他答案。例如,使用jQuery' $.extend({},originalObject)可能是一个好主意。

请注意,如果你不关心原型链(尽管你应该),你总是可以做一些非常简单的事情:

var Greet = function(){
    var result = {};
    that.SayHello.apply(result, arguments);
    return result;
}

如果您不关心旧浏览器(ECMAScript 5),那么您可以使用Object.create方法:

var Greet = function(){
    var result = Object.create(that.SayHello.prototype);
    that.SayHello.apply(result, arguments);
    return result;
}