0

以下は、私の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);ました。

ALLをに渡すにはどうすればよいGreetですか? argumentsthat.SayHelloを使用
して初期化する必要があることを知っていると、コードが壊れます。that.SayHellonew that.SayHello

任意の数の一般的な解決策を探しています。1つずつarguments渡したくありません。arguments

このコードはjsfiddleでも入手できます。

4

1 に答える 1

1

このようなもの?

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

objectにapply適用されることを知っておく必要があります。プロトタイプとして事前定義すると、必要なものが得られます。argumentsresultresultSayHello

編集

残念ながら、上記のコードは のプロトタイプを変更し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;
}

この回答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;
}
于 2012-04-06T13:27:30.147 に答える