2015-06-16 16 views
10

Jestem pewien, że jest to stosunkowo proste i że brakuje mi czegoś oczywistego. Czytam poprzez Mozilla's tutorials na ES6, a ich chapter on destructuring zawiera następujący wzór:Definicje parametrów funkcji w ES6

Funkcja Parametr definicje

Jako programistów, często możemy narazić bardziej ergonomicznych interfejsów API przyjmując pojedynczy obiekt z wieloma właściwości jako parametr zamiast zmuszają naszych klientów API do pamiętania o kolejności wielu pojedynczych parametrów . Możemy użyć destructuring aby uniknąć powtarzania tej pojedynczy obiekt parametru gdy chcemy odwoływać się jedną z jego właściwości:

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

To jest uproszczony fragment prawdziwego kodu światowej z DevTools Firefox JavaScript Debugger (który realizowany jest także w JavaScript-yo dawg). Ten wzór jest szczególnie przyjemny.

Nie rozumiem, jak to się ma do destrukturyzacji. Czy pomysł, abyś zezwolił na przekazanie obiektu do tej funkcji, która może być w dowolnej kolejności, o ile zawiera wszystkie elementy, tj. { line: 10, column: 20, url: 'localhost' }?

Jeśli tak, jakie są korzyści nad czymś takim

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

gdzie params jest obiektem z url, line i column? Czy pomysł polega tylko na tym, że wymuszasz Javascript, aby sprawdzić poprawność parametrów funkcji, gdy są używane w zniszczonym kontekście, jawnie je definiując?

+1

"Obiekt ... który może być w dowolnej kolejności, o ile zawiera wszystkie elementy" obiekty nie mają zamówienia, a ty nie musisz mieć wszystkich przedmiotów. Brak weryfikacji ani przetwarzania. Korzyścią jest to, że zamiast odniesienia do treści funkcji 'params.url',' params.line', 'params.column', możesz bezpośrednio odwoływać się do' url', 'line' i' column'. – Barney

+0

Ma sens dla mnie. – fox

+1

@Barney: Właściwości obiektu nie mają porządku w ** ES5 **. [Oni ** robią ** w ES6] (https://people.mozilla.org/~jorendorff/es6-draft.html#sec-ordinary-object-internal-methods-and-internal-slots-ownpropertykeys). –

Odpowiedz

15

Nie rozumiem, jak to się ma do destrukturyzacji.

ciągu removeBreakpoint, można użyć url, line i column bezpośrednio. Niszczenie odbywa się po wywołaniu removeBreakpoint z obiektem opcji; właściwości dopasowania tego obiektu są niszczone na pojedyncze argumenty.

jest pomysł, że pozwalasz możliwość przekazać obiekt do tej funkcji, które mogą być w dowolnej kolejności, o ile zawiera on wszystkie elementy, czyli {linii: 10, kolumna: 20, url: „localhost” }?

Tak, ale nie musi zawierać wszystkich przedmiotów; jeśli nie, to ponieważ argument jest inicjalizowany z właściwości obiektu, która nie istnieje, argumentem jest undefined (chyba że podana jest wartość domyślna).

Prosty przykład pokazując rozpad (Live Copy with ES5 translation na Babel „s 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" 
}); 

wyjściowa:

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

Jeśli tak, jakie są korzyści nad czymś jak

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

gdzie params jest obiektem z adresem URL, linią i kolumną?

Cukier syntaktyczny. Nowa składnia do akceptowania obiektów opcji jest bardziej zwięzła i deklaratywna, automatyzując wspólny wzorzec. Jest to szczególnie widoczne, jeśli połączyć je z wartościami domyślnymi (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(); 

wyjściowa:

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

powyżej, nawet opcji sam obiekt jest opcjonalny, dlatego prace ostatni połączeń :

removeBreakpoint(); 

Gdybyśmy nie otrzymują domyślne opcji sprzeciwić się, że rozmowa byłaby powiodło się, ponieważ chcemy być próbuje odczytać właściwość url z undefined. Czasami tego chcesz, więc możesz wyłączyć ogólną opcję. Innym razem nie.


Notatka: Zdolność do domyślnych części opcji sprzeciw, a także oddzielnie, cały Opcje obiektu prowadzi do ciekawej sytuacji, w której można zjeść różne domyślnie w zależności od tego, czy przedmiotem opcji dano ale nie mają określoną opcję vs. żadne opcje obiektu podana w ogóle, wszystko zrobić deklaratywnie: 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); 

wyjściowa:

 
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 
Powiązane problemy