Gibt es in ES6 (ES2015/JavaScript.next/Harmony) einen null
- sicheren Eigenschaftszugriff (Nullpropagation/Existenz), wie zum Beispiel?.
in CoffeeScript ? Oder ist es für ES7 geplant?
var aThing = getSomething()
...
aThing = possiblyNull?.thing
Das wird ungefähr so sein:
if (possiblyNull != null) aThing = possiblyNull.thing
Idealerweise sollte die Lösung undefined
nicht zuweisen (auch aThing
), wenn possiblyNull
null
ist.
Eine Funktion, die dies derzeit in Stufe 1 durchführt: Optionale Verkettung.
https://github.com/tc39/proposal-optional-chaining
Wenn Sie es heute verwenden möchten, gibt es ein Babel-Plugin, das dies bewerkstelligt.
https://github.com/davidyaha/ecmascript-optionals-vorschlag
Update (2017-08-01): Wenn Sie ein offizielles Plugin verwenden möchten, können Sie den Alpha-Build von Babel 7 mit der neuen Transformation testen. Ihre Laufleistung kann variieren
https://www.npmjs.com/package/babel-plugin-transform-optional-chaining
Es ist nicht so schön wie das? Operator, aber um ein ähnliches Ergebnis zu erzielen, könnten Sie Folgendes tun:
user && user.address && user.address.postcode
Da null
und undefined
beide falsy -Werte sind ( siehe diese Referenz ), wird auf die Eigenschaft nach dem &&
-Operator nur dann zugegriffen, wenn der Präzedenzfall nicht null oder undefiniert ist.
Alternativ können Sie eine Funktion wie folgt schreiben:
function _try(func, fallbackValue) {
try {
var value = func();
return (value === null || value === undefined) ? fallbackValue : value;
} catch (e) {
return fallbackValue;
}
}
Verwendungszweck:
_try(() => user.address.postcode) // return postcode or undefined
Oder mit einem Rückfallwert:
_try(() => user.address.postcode, "none") // return postcode or a custom string
Nein. In JavaScript können Sie lodash # get oder ähnliches verwenden.
Vanille-Alternative für den sicheren Zugang zu Immobilien
(((a.b || {}).c || {}).d || {}).e
Die prägnanteste bedingte Zuteilung wäre wahrscheinlich die folgende
try { b = a.b.c.d.e } catch(e) {}
Nein, in ES6 gibt es keinen Null-Propagierungsoperator. Sie müssen mit einem der bekannten Muster gehen.
Möglicherweise können Sie die Destrukturierung verwenden:
({thing: aThing} = possiblyNull);
Es gibt viele Diskussionen (z. B. this ), um einen solchen Operator in ES7 hinzuzufügen, aber keine hat sich wirklich durchgesetzt.
Nach der Liste hier gibt es derzeit keinen Vorschlag, eine sichere Durchreise zu Ecmascript hinzuzufügen. Es gibt also nicht nur einen schönen Weg, dies zu tun, sondern es wird in absehbarer Zeit nicht hinzugefügt.
Ich weiß, dass dies eine JavaScript-Frage ist, aber ich denke, dass Ruby dies auf alle angeforderten Arten erledigt. Ich denke, es ist ein relevanter Bezugspunkt.
.&
, try
und && haben ihre Stärken und möglichen Fallstricke. Eine große Auswahl dieser Optionen hier: http://mitrev.net/Ruby/2015/11/13/the-operator-in-Ruby/
TLDR; Die Schlussfolgerung der Rubyisten ist, dass Dig
sowohl augenfreundlicher ist als auch eine stärkere Garantie, dass ein Wert oder null
zugewiesen wird.
Hier ist eine einfache Implementierung in TypeScript:
export function Dig(target: any, ...keys: Array<string>): any {
let digged = target
for (const key of keys) {
if (typeof digged === 'undefined') {
return undefined // can also return null or a default value
}
if (typeof key === 'function') {
digged = key(digged)
} else {
digged = digged[key]
}
}
return digged
}
Dies kann für jede Schachtelungstiefe und für Funktionen verwendet werden.
a = Dig(b, 'c', 'd', 'e');
foo = () => ({});
bar = Dig(a, foo, 'b', 'c')
Der try
-Ansatz kann in JS genauso gut gelesen werden, wie in den vorherigen Antworten gezeigt. Es ist auch keine Schleife erforderlich, was ein Nachteil dieser Implementierung ist.
Eine sichere Deep-get-Methode scheint eine natürliche Voraussetzung für Underscore.js zu sein, aber das Problem besteht darin, die String-Programmierung zu vermeiden. Ändern der Antwort von @ Felipe, um die String-Programmierung zu vermeiden (oder Edge-Fälle zumindest an den Anrufer zurückschieben):
function safeGet(obj, props) {
return (props.length==1) ? obj[keys[0]] :safeGet(obj[props[0]], props.slice(1))
}
Beispiel:
var test = {
a: {
b: 'b property value',
c: { }
}
}
safeGet(test, ['a', 'b'])
safeGet(test, "a.b".split('.'))