wake-up-neo.com

Kein sicherer Eigenschaftszugriff (und bedingte Zuweisung) in ES6/2015

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 possiblyNullnull ist.

109
ııı

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

72
basicdays

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
41
tocqueville

Nein. In JavaScript können Sie lodash # get oder ähnliches verwenden.

28
Girafa

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) {}
10
yagger

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.

6
Bergi

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.

3
Antimony

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. 

0
theUtherSide

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('.'))  
0
prototype