2016-12-11 1 views
2

Ich habe einige Graph QL/React/Relay-Beispiele durchgearbeitet und bin in eine seltsame Syntax geraten. ES6 Fettpfeil und Klammern `(...) => ({...})`

Bei der Definition der Felder in Graph QL Objekte die folgende Syntax verwendet:

const xType = new GraphQLObjectType({ 
    name: 'X', 
    description: 'A made up type for example.', 
    fields:() => ({ 
    field: {/*etc.*/} 
    }) 
}); 

Von dem, was ich sammeln diese nur eine anonyme Funktion ist die Definition und es xType.fields zuweisen. Diese anonyme Funktion gibt das Objekt zurück, das die Felddefinitionen enthält.

Ich gehe davon aus, dass jedoch der Graph QL-Schemamechanismus funktioniert, der als eine Funktion definiert werden muss, die ein Objekt und nicht einfach ein Objekt zurückgibt. Aber der Teil, der mich verwirrt hat, ist die Klammer um die geschweiften Klammern.

Soll dies eine Objektdefinition von einer Funktionsdefinition unterscheiden? Ist es der Klarheit halber für den Leser?

Die einzige ähnliche Syntax, die eine Google-Suche gefunden hat, ist im airbnb style guide, wo es eine Lesbarkeit/Klarheit Sache scheint.

Nur auf der Suche nach Bestätigung oder eine Erklärung über meine Annahmen hinaus, wie ich anfange, mit Graph QL ein wenig mehr zu spielen.

+1

„Ist das eine Objektdefinition aus einer Funktionsdefinition zu unterscheiden? Ist es der Übersichtlichkeit halber für den Leser?“ Ja, genau das ist es. – Whymarrh

+1

Sie können weitere Informationen zu der duplizierten Frage erhalten, oder in diesem [MDN-Artikel] (https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Functions/Arrow_functions#Returning_object_literals). –

Antwort

10
fields:() => ({ 
    field: {/*etc.*/} 
}) 

ist eine Funktion, die implizit ein Objekt (literal) zurückgibt. Ohne Verwendung von () interpretiert der JavaScript-Interpreter die {} als Wrapper für den Funktionskörper und nicht als ein Objekt.

Ohne parens: () wird die field: ... Anweisung als label Anweisung behandelt und die Funktion gibt undefined zurück. Die entsprechende Syntax ist:

fields:() => { // start of the function body 
    // now we have to define an object 
    // and explicitly use the return keyword 
    return { field: {/*etc.*/} } 
} 

So sind Eltern nicht wegen der Klarheit. Es ist da, um implizit zurückkehrende Funktion von Pfeilfunktionen zu verwenden.

4

Es ist der Klarheit halber sowohl für den Compiler als auch für den Leser. Die field: Syntax in Ihrem Beispiel erscheint eine eindeutige Werbegeschenk zu sein, dass dies ein Objektliteral ist, aber diesen Code zum Beispiel nehmen:

let f =() => { 
 
    field: 'value' 
 
} 
 

 
console.log(f()) //=> undefined

Sie würden erwarten, dass dies ein Objekt mit field auf log zu 'value', aber es protokolliert undefined. Warum?

Wesentlichen, was Sie als Objekt sehen wörtliche mit einer einzigen Eigenschaft, sieht der Compiler als Funktion Körper (bezeichnet durch Öffnen und Schließen geschweiften Klammern, wie eine typische Funktion) und einer einzigen label statement, die die Syntax label: verwendet. Da der folgende Ausdruck nur eine Literalzeichenfolge ist und niemals zurückgegeben (oder gar einer Variablen zugewiesen) wird, tut die Funktion f() effektiv nichts, und ihr Ergebnis ist undefined.

Wenn Sie jedoch Klammern um Ihr "Objektliteral" setzen, weisen Sie den Compiler an, die gleichen Zeichen als Ausdruck und nicht als Bündel von Anweisungen zu behandeln, damit das gewünschte Objekt zurückgegeben wird. (Siehe this article on the Mozilla Development Network, im Kommentarbereich.

)

let g =() => ({ 
 
    field: 'value' 
 
}) 
 

 
console.log(g()) //=> { field: 'value' }