2016-04-16 23 views
5

Dire che ho una funzione per comporre un oggetto da altri oggetti, e sto passando argomenti alla funzione - inizialmente un oggetto letterale, e quindi gli oggetti che voglio comporre per estendere l'oggetto:Passare argomenti della funzione a Object.assign

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

il numero di argomenti passati è facoltativo, come faccio poi passare l'args per Object.assign() a partire dalla 2 ° arg. Così la funzione sarebbe simile al seguente:

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

Grazie in anticipo :)

+0

Hai già passato l'argomento dal secondo come 'arguments' è un array di argomenti passati alla funzione; – itzmukeshy7

+1

@ itzmukeshy7: Non è un array, ma solo un array (che è rilevante per la domanda). Ma penso che l'esempio fosse solo per mostrare il concetto di cosa volevano fare. Il problema è che il numero di argomenti è variabile. –

+0

@ le-moi 'arguments' è una matrice speciale che contiene tutti gli argomenti passati; – itzmukeshy7

risposta

5

Se stai usando ES2015 piuttosto che solo uno spessore , è possibile utilizzare la notazione diffusione, Array.from, e slice:

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

o semplicemente utilizzando slice direttamente piuttosto che dopo Array.from:

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

... vedere Thomas' answer utilizzando rest argomenti, poiché questo è il modo corretto di farlo in ES2015.

Se non stai usando ES2015, si può fare la stessa cosa con un solo spessorato Object.assign via apply:

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

C'è, stiamo usando Function#apply anziché l'operatore spread (dal ES5 e precedenti non avere l'operatore di spread). Function#apply chiama la funzione che viene chiamata utilizzando il primo argomento come this durante la chiamata, e utilizzando l'array (o la cosa simile a una matrice) gli si fornisce come secondo argomento gli argomenti per la chiamata.

Quindi dire che avete:

obj.foo(1, 2, 3); 

L'equivalente utilizzando Function#apply è:

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

Il primo argomento, obj, dice apply cosa usare come this durante la chiamata. Il secondo argomento è un array di argomenti da usare.

Ma se si utilizza l'operatore di spread, non ce n'è bisogno, estende il suo operando di tipo array in argomenti discreti.

+0

Bingo, grazie TJ. Potresti parlarmi di quello che sta succedendo, se non ti dispiace? Perché chiamiamo apply su Object.assign()? Inoltre, perché Object è il primo argomento da applicare? Cercando di capire cosa sta succedendo - è l'applicazione utilizzata per trattare gli argomenti restituiti perché sono convertiti in una matrice? –

+0

@LeMoi: l'ho aggiunto alla fine per spiegarlo, ma se si sta utilizzando l'operatore di spread di ES2015, non è necessario utilizzare 'apply'. –

+0

Grazie mille, è fantastico :) –

2

ES2015:

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

rest sarà un vero array di tutti gli argomenti a partire dalla seconda.

E il Babel-uscita:

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

Questo sembra essere un programma di utilità-funzione che potrebbe essere utilizzato in tutto il luogo. Non appena si passa arguments a un'altra funzione come Array.prototype.slice() o Array.from(), composeObj non sarà più ottimizzato dal compilatore JS. Quindi, non farlo.

Tutto il resto è già stato detto su T.J. Risposta di Crowders e commenti; solo mostrando la migliore implementazione.

+0

Se l'OP utilizza ES2015, questa dovrebbe essere la risposta accettata e chiunque utilizzi ES2015 con un problema simile dovrebbe seguire questo consiglio. (Dov'era la mia testa?) –

Problemi correlati