2016-03-11 9 views
10

supponiamo Ho il seguente oggetto:Come destrutturarsi in variabili con nome dinamico in ES6?

const user = { 
    id: 42, 
    displayName: "jdoe", 
    fullName: { 
     firstName: "John", 
     lastName: "Doe" 
    } 
}; 

e che voglio solo il id e fullName.

farò fare quanto segue:

const { id, fullName } = user 

facile peasy, giusto?

Ora supponiamo di voler eseguire la destrutturazione in base al valore di un'altra variabile denominata fields.

const fields = [ 'id', 'fullName' ] 

Ora la mia domanda è: Come posso fare destrutturazione sulla base di una serie di chiavi?

ho spudoratamente provato quanto segue senza successo:

let {[{...fields}]} = user e let {[...fields]} = user. C'è un modo in cui ciò potrebbe essere fatto?

Grazie

+1

Ecco una questione connessa su destrutturazione tutte le proprietà: http://stackoverflow.com/ domande/31907970/how-do-i-destructure-all-properties-in-the-current-scope-closure-in-es2015 - Probabilmente la stessa risposta si applica qui – CodingIntrigue

+0

Se i 'campi' sono stati modificati per essere un array vuoto, allora non creerebbe nessuna variabile e qualsiasi codice dopo sarebbe stato messo a repentaglio. L'uso di un const con valori letterali garantisce che il rischio possa essere determinato in anticipo ma qualcosa come 'fields = nonliteralvar' creerebbe problemi. –

risposta

4

Risposta breve: è impossibile e non sarà possibile.

Ragionamento alla base: introdurrebbe nuove variabili nominate dinamicamente in ambito di blocco, essendo effettivamente dinamico eval, disabilitando così qualsiasi ottimizzazione delle prestazioni. La dinamica eval che può modificare lo scope in volo è sempre stata considerata estremamente pericolosa e rimossa dalla modalità rigorosa ES5.

Inoltre, si tratterebbe di un codice olfatto - le variabili non definite di riferimento generano ReferenceError, quindi è necessario disporre di più codice di codice per gestire in modo sicuro tale ambito dinamico.

+0

Quello era davvero un odore di codice. Finito con un altro approccio. – Anass

+1

Il punto di riferimento che si aumenta è inattaccabile. C'è, tuttavia, almeno un caso in cui non è un odore di codice di per sé. I.e., quando si ha una funzione che accetta una chiave o chiavi da utilizzare in iterazione. Le versioni speciali di 'omit',' pluck' e 'reduce' sono tutti casi in cui la destrutturazione dinamica aiuterebbe la leggibilità. L'allocazione dinamica dei nomi di campo in un oggetto è sia possibile sia un ottimo modo per abilitare il codice DRYer (cioè più condivisione di codice). Allo stesso modo, l'allocazione dinamica dei puntatori potrebbe aiutare a DEUMARE il codice senza dover utilizzare una hashmap per eludere una limitazione della lingua. –

6

Non è impossibile distruggersi con una chiave dinamica. Per evitare il problema della creazione di variabili dinamiche (come menzionato da Ginden) è necessario fornire degli alias.

const user = { 
    id: 42, 
    displayName: "jdoe", 
    fullName: { 
     firstName: "John", 
     lastName: "Doe" 
    } 
}; 

const fields = [ 'id', 'fullName' ]; 
const object = {}; 

const {[fields[0]]: id, [fields[1]]: fullName} = user; 

console.log(id); // 42 
console.log(fullName); // { firstName: "John", lastName: "Doe" } 

per aggirare il problema di dover definire alias statici per i valori dinamici, è possibile assegnare alle proprietà dinamiche di un oggetto. In questo semplice esempio, questo è lo stesso ripristinando tutta destrutturazione, però :)

const user = { 
    id: 42, 
    displayName: "jdoe", 
    fullName: { 
     firstName: "John", 
     lastName: "Doe" 
    } 
}; 

const fields = [ 'id', 'fullName' ]; 
const object = {}; 

({[fields[0]]: object[fields[0]], [fields[1]]: object[fields[1]]} = user); 

console.log(object.id); // 42 
console.log(object.fullName); // { firstName: "John", lastName: "Doe" } 

fonti:

+2

Sfortunatamente nessuna delle soluzioni proposte risponde alla domanda come richiesto. –

0

Come discusso prima, non puoi distruggerti in vari nomi con nomi dinamici abilita in JavaScript senza utilizzare eval.

Ma è possibile ottenere un sottoinsieme dell'oggetto in modo dinamico, utilizzando ridurre la funzione come segue:

const destruct = (keys, obj) => 
 
    keys.reduce((a, c) => ({ ...a, [c]: obj[c] }), {}); 
 

 
const object = { 
 
    color: 'red', 
 
    size: 'big', 
 
    amount: 10, 
 
}; 
 

 
const subset = destruct(['color', 'amount'], object); 
 
console.log(subset);

Problemi correlati