aboutsummaryrefslogtreecommitdiff
path: root/files/de/web/javascript/reference/operators/optionale_verkettung/index.html
blob: 8ef763b3cd2b24a0efa6817a54d67ccf9094377e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
---
title: Optionale Verkettung
slug: Web/JavaScript/Reference/Operators/Optionale_Verkettung
tags:
  - Experimentell
  - JavaScript
  - Operator
  - Optionale Verkettung
  - Referenz
  - Verkettung
translation_of: Web/JavaScript/Reference/Operators/Optional_chaining
---
<div>{{JSSidebar("Operators")}}</div>

<p>{{SeeCompatTable}}</p>

<p>Der <strong>Optionale-Verkettung</strong>s-Operator (Optional Chaining) <strong><code>?.</code></strong> ermöglicht es, einen Wert aus einer Eigenschaft tief innerhalb einer Verkettung von Objekt-Eigenschaften auszulesen, ohne dabei explizit überprüfen zu müssen, ob jede Referenz in der Kette valide ist.<span class="seoSummary">Der <code>?.</code> Operator funktioniert ähnlich wie der <code>.</code> -Verkettungs Operator, außer dass er keinen Fehler bei einem {{glossary("nullish")}} ({{JSxRef("null")}} oder {{JSxRef("undefined")}}) Wert auswirft, sondern stattdessen den Ausdruck beendet und <code>undefined</code> zurückgibt.</span> Wird er mit Funktionsaufrufen verwendet, wirft der Aufruf <code>undefined</code> zurück, wenn die Funktion nicht existiert.</p>

<p>Das Ergebnis sind kürzere und einfacherere Anweisungen wenn auf verkettete Eigenschaften zugegriffen wird, bei denen die Möglichkeit besteht, dass sie fehlen. Er kann außerdem hilfreich sein, wenn man den Inhalt eines Objektes erhalten möchte wenn es keine Garantie dafür gibt welche Eigenschaften benötigt werden.</p>

<div>{{EmbedInteractiveExample("pages/js/expressions-optionalchainingoperator.html")}}</div>

<div></div>



<h2 id="Syntax">Syntax</h2>

<pre class="syntaxbox"><var>obj</var>?.<var>prop</var>
<var>obj</var>?.[<var>expr</var>]
<em>arr</em>?.[<var>index</var>]
<var>func</var>?.(<var>args</var>)
</pre>

<h2 id="Beschreibung">Beschreibung</h2>

<p>Der Optionale-Verkettungs-Operator ermöglicht einen Weg auf Werte in einer Verkettung aus Eigenschaften zuzugreifen, wenn die Möglichkeit existiert, dass eine der Referenzen oder Funktionen in der Kette <code>undefined</code> oder <code>null</code> sind.</p>

<p>Als Beispiel nehmen wir ein Objekt <code>obj</code>, dass eine verschachtelte Struktur besitzt. Ohne Optionale Verkettung müssen wir beim Zugriff auf einen Wert jede Referenz innerhalb der Kette auf ihre Existenz überprüfen:</p>

<pre class="brush: js">let nestedProp = obj.first &amp;&amp; obj.first.second;</pre>

<p>Der Wert von <code>obj.first</code> wird darauf geprüft nicht-<code>null</code> (und nicht-<code>undefined</code>) zu sein und erst dann greifen wir auf den Wert <code>obj.first.second</code> zu. Dies verhindet einen Fehler der auftreten würde wenn wir direkt <code>obj.first.second</code> ansprechen ohne zuvor <code>obj.first</code> zu prüfen.</p>

<p>Mit dem Optionale-Verkettungs-Operator (<code>?.</code>) allerdings müssen wir nicht explizit testen und können eine Abkürzung auf Basis des Wertes von <code>obj.first</code> nutzen bevor auf auf <code>obj.first.second</code> zugreifen:</p>

<pre class="brush: js">let nestedProp = obj.first?.second;</pre>

<p>Durch die Verwendung des <code>?.</code>-Operators statt nur dem <code>.</code> stellet JavaScript sicher, dass zuvor geprüft wird ob <code>obj.first</code> nicht <code>null</code> oder <code>undefined</code> ist bevor auf <code>obj.first.second</code> zugegriffen wird. Wenn <code>obj.first</code> <code>null</code> oder <code>undefined</code> ist, wird der Ausdruck automatisch sofort beendet und wirft den Wert <code>undefined</code> zurück</p>

<p>Das ist dasselbe wie folgender Ausdruck:</p>

<pre class="brush: js">let nestedProp = ((obj.first === null || obj.first === undefined) ? undefined : obj.first.second);</pre>

<h3 id="Optionale_Verkettung_mit_Funktionsaufrufen">Optionale Verkettung mit Funktionsaufrufen</h3>

<p>Optionale Verkettung kann verwendet werden um Funktionen aufzurufen, die womöglich nicht existeiren. Das kann hilfreich sein wenn man z.B. eine API verwenden möchte die möglicherweise nicht verfügbar ist, entweder durch das Alter der Implementierung oder weil die Funktionalität nicht für das Gerät verfügbar ist.</p>

<p>Verwendet man optionale Verkettung mit Funktionsaufrufen, wird der Ausdruck automatisch <code>undefined</code> zurückwerfen, sollte die Funktion nicht existieren:</p>

<pre class="brush: js">let result = someInterface.customMethod?.();</pre>

<div class="blockIndicator note">
<p><strong>Note:</strong> Wenn eine Eigenschaft mit dem Namen existiert, die aber keine Funktion ist, wird <code>?.</code> trotzdem eine {{JSxRef("TypeError")}} Ausnahme auslösen (<code>x.y</code><code> ist keine Funktion</code>).</p>
</div>

<h4 id="Optionale_Callbacks_oder_Event_Handler_handhaben">Optionale Callbacks oder Event Handler handhaben</h4>

<p>If you use callbacks or fetch methods from an object with <a href="/en-US/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment#Object_destructuring">a destructuring assignment</a>, you may have non-existent values that you cannot call as functions unless you have tested their existence. Using <code>?.</code>, you can avoid this extra test:</p>

<pre class="brush: js">// Written as of ES2019
function doSomething(onContent, onError) {
  try {
    // ... do something with the data
  }
  catch (err) {
    if (onError) { // Testing if onError really exists
      onError(err.message);
    }
  }
}
</pre>

<pre class="brush: js">// Using optional chaining with function calls
function doSomething(onContent, onError) {
  try {
   // ... do something with the data
  }
  catch (err) {
    onError?.(err.message); // no exception if onError is undefined
  }
}
</pre>

<h3 id="Optional_chaining_with_expressions">Optional chaining with expressions</h3>

<p>You can also use the optional chaining operator when accessing properties with an expression using <a href="/en-US/docs/Web/JavaScript/Reference/Operators/Property_Accessors#Bracket_notation">the bracket notation of the property accessor</a>:</p>

<pre class="brush: js">let nestedProp = obj?.['prop' + 'Name'];
</pre>

<h3 id="Array_item_access_with_optional_chaining">Array item access with optional chaining</h3>

<pre class="brush: js">let arrayItem = arr?.[42];</pre>

<h2 id="Examples">Examples</h2>

<h3 id="Basic_example">Basic example</h3>

<p>This example looks for the value of the <code>name</code> property for the member <code>bar</code> in a map when there is no such member. The result is therefore <code>undefined</code>.</p>

<pre class="brush: js">let myMap = new Map();
myMap.set("foo", {name: "baz", desc: "inga"});

let nameBar = myMap.get("bar")?.name;</pre>

<h3 id="Short-circuiting_evaluation">Short-circuiting evaluation</h3>

<p>When using optional chaining with expressions, if the left operand is <code>null</code> or <code>undefined</code>, the expression will not be evaluated. For instance:</p>

<pre class="brush: js">let potentiallyNullObj = null;
let x = 0;
let prop = potentiallyNullObj?.[x++];

console.log(x); // 0 as x was not incremented
</pre>

<h3 id="Stacking_the_optional_chaining_operator">Stacking the optional chaining operator</h3>

<p>With nested structures, it is possible to use optional chaining multiple times:</p>

<pre class="brush: js">let customer = {
  name: "Carl",
  details: {
    age: 82,
    location: "Paradise Falls" // detailed address is unknown
  }
};
let customerCity = customer.details?.address?.city;

// … this also works with optional chaining function call
let duration = vacations.trip?.getTime?.();
</pre>

<h3 id="Combining_with_the_nullish_coalescing_operator">Combining with the nullish coalescing operator</h3>

<p>The nullish coalescing operator may be used after optional chaining in order to build a default value when none was found:</p>

<pre class="brush: js">let customer = {
  name: "Carl",
  details: { age: 82 }
};
const customerCity = customer?.city ?? "Unknown city";
console.log(customerCity); // Unknown city</pre>

<h2 id="Specifications">Specifications</h2>

<table class="standard-table">
 <thead>
  <tr>
   <th scope="col">Specification</th>
   <th scope="col">Status</th>
   <th scope="col">Comment</th>
  </tr>
 </thead>
 <tbody>
  <tr>
   <td><a href="https://tc39.es/proposal-optional-chaining/#top">Proposal for the "optional chaining" operator</a></td>
   <td>Stage 4</td>
   <td></td>
  </tr>
 </tbody>
</table>

<h2 id="Browser_compatibility">Browser compatibility</h2>

<div>


<p>{{Compat("javascript.operators.optional_chaining")}}</p>
</div>

<h3 id="Implementation_Progress">Implementation Progress</h3>

<p>The following table provides a daily implementation status for this feature, because this feature has not yet reached cross-browser stability. The data is generated by running the relevant feature tests in <a href="https://github.com/tc39/test262">Test262</a>, the standard test suite of JavaScript, in the nightly build, or latest release of each browser's JavaScript engine.</p>

<div>{{EmbedTest262ReportResultsTable("optional-chaining")}}</div>

<h2 id="See_also">See also</h2>

<ul>
 <li>The {{JSxRef("Operators/Nullish_Coalescing_Operator", "Nullish Coalescing Operator", '', 1)}}</li>
 <li><a href="https://github.com/tc39/proposals">TC39 proposals</a></li>
</ul>