2015-08-21 2 views
70

Gibt es einen null -safe Eigenschaft Zugang (null Ausbreitung/Existenz) Operator in ES6 (ES2015/JavaScript.next/Harmonie) wie ?. in Coffee zum Beispiel? Oder ist es für ES7 geplant?Null sichere Zugriff auf Eigenschaften (und bedingte Zuweisung) in ES6/2015

var aThing = getSomething() 
... 
aThing = possiblyNull?.thing 

Dies wird in etwa wie:

if (possiblyNull != null) aThing = possiblyNull.thing 

Idealerweise sollte die Lösung nicht (auch undefined) zuweisen aThing wenn possiblyNull ist null

+1

@naomik Diese Art von null Prüfung kann variieren kann sehr nützlich sein für die if-Anweisungen, wo sie eine tief verschachtelte Eigenschaft sind die Überprüfung, zum Beispiel 'if (obj? .nested? .property? .value)' anstelle von 'if (obj && obj.nested && obj.nested.property && obj.nested.property.value) ' –

+0

@SeanWalsh wenn Ihre Objekte so tief sind verschachtelt, oder wenn Ihre Funktionen so tief in Ihren Objekten graben, gibt es wahrscheinlich auch noch andere Probleme mit Ihrer App. – naomik

+1

vergleichen 'var appConfig = loadConfig (config, process.env); connect (appConfig.database); 'to' connect (config) '. Sie können ein viel einfacheres Objekt an 'connect' übergeben, anstatt das ganze' config'-Objekt zu übergeben. Sie können 'conf.username',' conf.password' anstelle von etwas wie 'config [process.env] ?. database verwenden ? .username', 'config [process.env] ?. database? .password'. Referenz: [Gesetz von Demeter] (https://en.wikipedia.org/wiki/Law_of_Demeter). – naomik

Antwort

46

Eine Funktion, die das erreicht ist derzeit in Phase 1: Optionales Verketten.

https://github.com/tc39/proposal-optional-chaining

Wenn Sie heute wollen, es zu benutzen, ist es eine Babel-Plugin, das das erreicht.

https://github.com/davidyaha/ecmascript-optionals-proposal

aktualisieren (2017.08.01): Wenn Sie ein offizielles Plugin verwenden möchten, können Sie die Alpha-Version von Babel 7 mit dem neuen versuchen zu verwandeln. Ihre Kilometer

https://www.npmjs.com/package/babel-plugin-transform-optional-chaining

+0

Verstehe ich richtig, dass das jedoch keine bedingte Zuweisung enthält? 'street = user.address? .street' würde in jedem Fall' street' setzen? –

+0

Eigentlich denke ich leider, dass du recht hast. 'Street' _Ich denke_ würde" undefiniert "zugewiesen werden. _But_ zumindest würde es nicht versuchen, auf Eigenschaften auf undefined zuzugreifen. – basicdays

+1

Es sieht auch so aus als ob Sie den Operator auf der linken Seite haben können und wenn es etwas zu undefiniert macht, wird die rechte Hand nicht ausgewertet. Das Babel-Plugin kann ein wenig variieren, habe es selbst noch nicht getestet. – basicdays

23

Nein, Sie lodash#get oder etwas ähnliches verwenden dafür in JavaScript.

+1

Gibt es Vorschläge, ES7 hinzuzufügen? –

+1

Ich habe keine gefunden. – Girafa

+3

@PeterVarga: Viele. Zu viel Diskussion. Grammatik ist keine einfache Sache für dieses Merkmal – Bergi

6

Nein, in ES6 gibt es keinen Null-Propagierungsoperator. Sie müssen mit einem der known patterns gehen.

Unter Umständen können Sie Destrukturierung verwenden, aber:

({thing: aThing} = possiblyNull); 

Es gibt viele Diskussionen sind (z this) einen solchen Operator in ES7 hinzuzufügen, aber keiner ging die Post ab.

+0

Das sah vielversprechend aus, aber zumindest, was Babel damit macht, ist nicht anders als nur 'aThing = possibleNull.thing' –

+1

@PeterVarga: Ups, du hast Recht, Destrukturierung funktioniert, wenn die Eigenschaft nicht existiert, aber nicht wenn Objekt ist "null". Sie müssten einen Standardwert angeben, ähnlich wie [dieses Muster] (http://stackoverflow.com/a/4034468/1048572), aber mit einer verwirrenderen Syntax. – Bergi

7

Vanilla Alternative für einen sicheren Zugriff auf Eigenschaften

(((a.b || {}).c || {}).d || {}).e 

Die knappste bedingte Zuweisung wahrscheinlich diese

try { b = a.b.c.d.e } catch(e) {} 
+0

Also, wie würdest du die Aufgabe in der Frage mit diesem Mechanismus schreiben? Brauchen Sie immer noch eine Bedingung, die nicht zugewiesen werden soll, falls die 'mayableNull' nicht definiert ist /' null'? –

+0

Sicher, Sie müssen immer noch überprüfen, ob eine Zuweisung passieren soll oder nicht. Wenn Sie den Operator '=' verwenden, wird unweigerlich etwas zugewiesen, sei es eine Daten, eine undefinierte oder Null. Das oben genannte ist also nur eine sichere Eigenschaft Zugang. Gibt es den bedingten Zuweisungsoperator überhaupt in jeder Sprache? – yagger

+0

Natürlich, zum Beispiel ** CoffeeScript **, hat es auch '|| =' –

3

Going durch die Liste here, gibt es derzeit kein Vorschlag sicher Traversal hinzuzufügen EcmaScript wäre . Es gibt also nicht nur keine gute Möglichkeit, dies zu tun, sondern es wird in absehbarer Zukunft nicht hinzugefügt werden.

19

Es ist nicht so schön wie die?. Betreiber, aber ein ähnliches Ergebnis zu erzielen, die Sie tun können:

user && user.address && user.address.postcode 

Da null und undefined sind beide falsy Werte (see this reference), das Eigentum nach dem && Betreiber nur, wenn der Präzedenzfall es nicht null oder nicht definiert zugegriffen wird .

Alternativ könnten Sie eine Funktion wie folgt schreiben:

function safeAccess(func, fallbackValue) { 
    try { 
     return func(); 
    } catch (e) { 
     return fallbackValue; 
    } 
} 

Verbrauch:

safeAccess(() => myCompany.people[0].age) // returns age or undefined 

Oder mit einem Fehlerwert:

safeAccess(() => myCompany.people[0].age, 0) // returns age or 0 
+0

Richtig wahrscheinlich sollte ich die Frage klären, die Hauptsache, nach der ich war, war bedingte Zuweisung –

+0

nur eine logische Folge dazu; Um die Inverse sicher zu finden, können Sie 'verwenden! (user && user.address && user.address.postcode)' :) – rob2d

+0

'foo && foo.bar && foo.bar.quux ...In einer großen Codebase ist das hässlich und fügt eine Menge Komplexität hinzu, die Sie besser vermeiden sollten. –