2015-06-16 21 views
10

Sono sicuro che questo è relativamente semplice e che mi manca qualcosa di ovvio. Sto leggendo attraverso Mozilla's tutorials su ES6, e la loro chapter on destructuring contiene il seguente schema:Definizioni dei parametri di funzione in ES6

FUNZIONE PARAMETRO DEFINIZIONI

Come sviluppatori, possiamo esporre spesso API più ergonomico, accettando un singolo oggetto con più le proprietà come parametro anziché obbligano i nostri utenti API a ricordare l'ordine di molti singoli parametri . Possiamo usare destrutturazione per evitare di ripetere questo singolo oggetto parametro ogni volta che vogliamo fare riferimento a una delle sue proprietà:

function removeBreakpoint({ url, line, column }) { 
    // ... 
} 

Questo è un frammento semplificata del codice mondo reale dal DevTools Firefox debugger JavaScript (che è anche implementato in JavaScript-yo dawg). Abbiamo trovato questo modello particolarmente piacevole.

Quello che non capisco è come questo si riferisce alla destrutturazione. L'idea che autorizzi la possibilità di passare un oggetto in questa funzione che può essere in ordine arbitrario purché contenga tutti gli elementi, ad esempio { line: 10, column: 20, url: 'localhost' }?

Se sì, qual è il beneficio più di qualcosa come

function removeBreakpoint(params) { 
    // ... 
} 

dove params è un oggetto con url, line, e column? L'idea è solo quella di forzare Javascript a convalidare i parametri di una funzione quando vengono utilizzati in un contesto destrutturato definendoli esplicitamente?

+1

"un oggetto ... che può essere in ordine arbitrario fintanto che contiene tutti gli oggetti" gli oggetti non hanno un ordine e non è necessario disporre di tutti gli elementi. Nessuna convalida o elaborazione si verifica. Il vantaggio è che anziché avere il riferimento alla funzione corpo 'params.url',' params.line', 'params.column', puoi fare riferimento a' url', 'line' e' column' direttamente. – Barney

+0

Ha senso per me. – fox

+1

@Barney: le proprietà degli oggetti non hanno ordine in ** ES5 **. [Loro ** fanno ** in ES6] (https://people.mozilla.org/~jorendorff/es6-draft.html#sec-ordinary-object-internal-methods-and-internal-slots-ownpropertykeys). –

risposta

15

Quello che non capisco è come questo si riferisce alla destrutturazione.

All'interno removeBreakpoint, è possibile utilizzare url, line e column direttamente. La destrutturazione avviene quando viene chiamato removeBreakpoint con un oggetto opzioni; le proprietà corrispondenti di quell'oggetto vengono destrutturate in singoli argomenti.

È l'idea che si consente la possibilità di passare un oggetto in questa funzione che può essere in ordine arbitrario purché contenga tutti gli elementi, ad esempio {riga: 10, colonna: 20, url: 'localhost' }?

Sì, ma non deve contenere tutti gli articoli; in caso contrario, poiché l'argomento è inizializzato da una proprietà dell'oggetto che non esiste, l'argomento è undefined (a meno che non venga specificato un valore predefinito).

Semplice esempio che dimostra la destrutturazione (Live Copy with ES5 translation sulla s' Babel REPL):

"use strict"; 
function removeBreakpoint({ url, line, column }) { 
    console.log("removeBreakpoint:"); 
    console.log("url: " + url); 
    console.log("line: " + line); 
    console.log("column: " + column); 
} 
removeBreakpoint({ 
    url: "the url", 
    line: "the line", 
    column: "the column" 
}); 
removeBreakpoint({ 
    url: "the url", 
    line: "the line" 
}); 

uscita:

 
removeBreakpoint: 
url: the url 
line: the line 
column: the column 
removeBreakpoint: 
url: the url 
line: the line 
column: undefined 

Se sì, qual è il beneficio più di qualcosa come

function removeBreakpoint(params) { 
    // ... 
} 

dove params è un oggetto con url, linea e colonna?

zucchero sintattico. La nuova sintassi per accettare gli oggetti delle opzioni è più concisa e dichiarativa, automatizzando un modello comune. Ciò è particolarmente evidente quando si combinano con i valori di default (Live Copy):

"use strict"; 
function removeBreakpoint(
    {        // <= { starts destructuring arg 
     url = "url default",  // <= Default for `url` 
     line = "line default",  // <= ...for `line` 
     column = "column default" // <= ...for `column` 
    }        // <= } ends destructuring arg 
    = {}       // <= Default for the options object iself 
) {         // (see notes after the code block) 
    console.log("removeBreakpoint:"); 
    console.log(url); 
    console.log(line); 
    console.log(column); 
} 
removeBreakpoint({ 
    url: "the url", 
    line: "the line", 
    column: "the column" 
}); 
removeBreakpoint({ 
    url: "the url", 
    line: "the line" 
}); 
removeBreakpoint(); 

uscita:

 
removeBreakpoint: 
the url 
the line 
the column 
removeBreakpoint: 
the url 
the line 
column default 
removeBreakpoint: 
url default 
line default 
column default 

in quanto sopra, anche le opzioni oggetto stesso è facoltativo, motivo per cui le opere ultima chiamata :

removeBreakpoint(); 

Se non avessimo dato un valore predefinito per le opzioni di per sé oggetto, che la chiamata sarebbe fallito perché saremmo cercando di leggere la proprietà url di undefined. A volte lo vuoi, e così lasceresti l'opzione generale. Altre volte no.


Nota a margine: la capacità di default parti delle opzioni oggetto e anche, separatamente, l'intero opzioni oggetto porta ad una situazione interessante dove si può avere diversi predefiniti a seconda se è stato dato un oggetto opzioni, ma non aveva una specifica opzione vs nessuna opzione oggetto che viene dato a tutti, tutto fatto in modo dichiarativo: Live Copy

"use strict"; 
function test(
    num, 
    { 
     foo = "foo default", 
     bar = "options given without bar" 
    } = {bar: "options not given at all"} 
) { 
    console.log(num + ": foo = " + foo + ", bar = " + bar); 
} 
test(1, {foo: "foo value", bar: "options given with bar"}); 
test(2, {bar: "options given with bar"}); 
test(3, {}); 
test(4); 

uscita:

 
1: foo = foo value, bar = options given with bar 
2: foo = foo default, bar = options given with bar 
3: foo = foo default, bar = options given without bar 
4: foo = foo default, bar = options not given at all