2016-04-16 14 views
5

他のオブジェクトからオブジェクトを作成する関数があり、関数に引数を渡しているとします。最初はオブジェクトリテラル、次にオブジェクトを作成するオブジェクトです。Object.assignへの関数引数の受け渡し

composeFunc({}, obj1, obj2, obj3); 

渡される引数の数はどのように私はその後、第2引数で始まるObject.assign()に引数を渡すか、オプションです。だから、この関数は次のようになります。

function composeObj(objs) { 
    return Object.assign(arguments[1], arguments[2], arguments[3]... etc); 
} 

事前に感謝:)

+0

'arguments'はfunctionに渡される引数の配列なので、すでに2番目の引数を渡しています。 – itzmukeshy7

+1

@ itzmukeshy7:配列ではなく、配列に似ています(これは質問に関連しています)。しかし、私はその例が彼らがしたいことの概念を示すことに過ぎないと思う。問題は、引数の数が可変であることです。 –

+0

@ le-moi 'arguments'は、引数がすべて渡された特別な配列です。 – itzmukeshy7

答えて

5

あなたはES2015だけではなく、シムを使用している場合は、スプレッド表記を使用することができ、Array.from、およびslice

function composeObj(objs) { 
    return Object.assign(...Array.from(arguments).slice(1)); 
} 

それともsliceを使用して、直接ではなく、Array.from後:

function composeObj(objs) { 
    return Object.assign(...Array.prototype.slice.call(arguments, 1)); 
} 

...残りのargsを使用してThomas' answerを参照してください。これはES2015でこれを行う正しい方法です。 (ES5およびそれ以前以来あり

function composeObj(objs) { 
    return Object.assign.apply(Object, Array.prototype.slice.call(arguments, 1)); 
} 

、我々は代わりに広がりオペレータのFunction#applyを使用している:あなたはES2015を使用していない場合

は、あなただけのシムObject.assignapply経由で同じことを行うことができますスプレッドオペレータを持たない)。 Function#applyは、呼び出し中に最初の引数をthisとして呼び出し、配列(または配列のようなもの)を呼び出しの引数として2番目の引数として使用して呼び出す関数を呼び出します。

あなたが持っていると言う:

obj.foo(1, 2, 3); 

同等Function#applyを使用すると、次のとおりです。

obj.foo.apply(obj, [1, 2, 3]); 

最初の引数、obj、通話中にthisとして使用するものをapplyを伝えます。 2番目の引数は、使用する引数の配列です。

拡散演算子を使用する場合は、配列のようなオペランドを離散引数に展開する必要はありません。

+0

ビンゴ、ありがとうTJ。あなたが気にしないなら、何が起こっているかを通して私に話すことができますか? なぜObject.assign()でapplyを呼び出すのですか? Objectが最初に適用する理由は何ですか? 何が起きているのか私の頭の中で解決しようとしています - 返された引数がArrayに変換されているため、その扱いに使用されていますか? –

+0

@LeMoi:これを説明するために最後に追加しましたが、ES2015のスプレッド演算子を使用している場合は、 'apply'を使う必要はありません。 –

+0

ありがとう、華麗です:) –

2

ES2015:

function composeObj(objs, ...rest){ 
    return Object.assign(...rest); 
} 

restは、第1から始まるすべての引数の真の配列であろう。

そしてバベル-出力:

function composeObj(objs) { 
    for (var _len = arguments.length, rest = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) { 
    rest[_key - 1] = arguments[_key]; 
    } 

    return Object.assign.apply(Object, rest); 
} 

これは、すべての場所で使用されるかもしれない効用関数であるように思われます。 argumentsArray.prototype.slice()またはArray.from()のような他の関数に渡すとすぐに、composeObjはJSコンパイラによってもう最適化されません。だから、しないでください。

他のものはすべて既にT.J.クラウダーの回答とコメント;単により良い実装を示しています。

+0

OPがES2015を使用している場合は、これが受け入れられる回答であり、同様の問題を持つES2015を使用している人は、このアドバイスに従ってください。 (私の頭はどこですか?) –

関連する問題