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
|
---
title: Optional chaining
slug: Web/JavaScript/Reference/Operators/Optional_chaining
translation_of: Web/JavaScript/Reference/Operators/Optional_chaining
---
<div>{{JSSidebar("Operators")}}</div>
<p>{{SeeCompatTable}}</p>
<p><strong>optional chaining</strong> 연산자 <strong><code>?.</code></strong> 는 체인의 각 참조가 유효한지 명시적으로 검증하지 않고, 연결된 객체 체인 내에 깊숙이 위치한 속성 값을 읽을 수 있다. <span class="seoSummary"><code>?.</code> 연산자는 <code>.</code> 체이닝 연산자와 유사하게 작동하지만, 만약 참조가 {{glossary("nullish")}} ({{JSxRef("null")}} 또는 {{JSxRef("undefined")}})이라면, 에러가 발생하는 것 대신에 표현식의 리턴 값은 <code>undefined</code>로 단락된다.</span> 함수 호출에서 사용될 때, 만약 주어진 함수가 존재하지 않는다면, <code>undefined</code>를 리턴한다.</p>
<p>이것은 참조가 누락될 가능성이 있는 경우 연결된 속성으로 접근할 때 더 짧고 간단한 표현식이 생성된다. 어떤 속성이 필요한지에 대한 보증이 확실하지 않는 경우 객체의 내용을 탐색하는 동안 도움이 될 수 있다.</p>
<div>{{EmbedInteractiveExample("pages/js/expressions-optionalchainingoperator.html")}}</div>
<div></div>
<p class="hidden">이 대화식 예제의 소스는 GitHub repository에 저장된다. 만약 너가 대화식 예제 프로젝트에 기여하려면, <a href="https://github.com/mdn/interactive-examples">https://github.com/mdn/interactive-examples</a>를 복제(clone)하고 풀 리퀘스트를 보내라.</p>
<h2 id="문법">문법</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="설명">설명</h2>
<p>optional chaining 연산자는 참조나 기능이 <code>undefined</code> 또는 <code>null</code>일 수 있을 때 연결된 객체의 값에 접근하는 단순화할 수 있는 방법을 제공한다.</p>
<p>예를 들어, 중첩된 구조를 가진 객체에서 <code>obj</code>가 있다. optional chaining이 없이 깊이 중첩된 하위 속성을 찾으려면, 다음과 같이 참조를 확인해야 한다:</p>
<pre class="brush: js">let nestedProp = obj.first && obj.first.second;</pre>
<p><code>obj.first</code>의 값은 <code>obj.first.second</code>의 값에 접근하기 전에 <code>null</code> (그리고 <code>undefined</code>)가 아니라는 점을 검증한다. 이는 만약에 <code>obj.first</code>를 테스트 없이 <code>obj.first.second</code> 에 직접 접근할 때 일어날 수 있는 에러를 방지한다. </p>
<p>그러나 optional chaining 연산자(<code>?.</code>)를 사용하여, <code>obj.first.second</code> 에 접근하기 전에 <code>obj.first</code>의 상태에 따라 명시적으로 테스트하거나 단락시키지 않아도 된다:</p>
<pre class="brush: js">let nestedProp = obj.first?.second;</pre>
<p><code>.</code> 대신에 <code>?.</code> 연산자를 사용함으로써, 자바스크립트는 <code>obj.first.second</code>에 접근하기 전에 <code>obj.first</code>가 <code>null</code> 또는 <code>undefined</code>가 아니라는 것을 암묵적으로 확인하는 것을 알고 있다. 만약 <code>obj.first</code>가 <code>null</code> 또는 <code>undefined</code>이라면, 그 표현식은 자동으로 단락되어 <code>undefined</code>가 반환된다.</p>
<p>이는 다음과 같다:</p>
<pre class="brush: js">let nestedProp = ((obj.first === null || obj.first === undefined) ? undefined : obj.first.second);</pre>
<h3 id="함수의_호출과_Optional_chaining">함수의 호출과 Optional chaining</h3>
<p>존재하지 않을 수 있는 매서드를 호출할 때, optional chaining을 사용할 수 있다. 예를 들어, 구현 기간이나 사용자 장치에서 사용할 수 없는 기능 때문에 메서드를 사용할 수 없는 API를 사용할 경우, 유용할 수 있다.</p>
<p>함수 호출과 optional chaining을 사용함으로써 메서드를 찾을 수 없는 경우에 예외를 발생시키는 것 대신에 그 표현식은 자동으로 <code>undefined</code>를 반환한다:</p>
<pre class="brush: js">let result = someInterface.customMethod?.();</pre>
<div class="blockIndicator note">
<p><strong>메모:</strong> 만약 속성에 해당 이름이 있지만 함수가 아니라면, <code>?.</code>의 사용은 여전히 예외를 발생시킨다. {{JSxRef("TypeError")}} exception (<code>x.y</code><code> is not a function</code>).</p>
</div>
<h4 id="optional_callbacks과_event_handlers_다루기">optional callbacks과 event handlers 다루기</h4>
<p>만약 객체에서 <a href="/en-US/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment#Object_destructuring">destructuring assignment</a>로 callbacks 또는 fetch 메서드를 사용한다면, 그 존재 여부를 테스트하지 않으면 함수로 호출할 수 없는 존재 하지 않는 값을 가질 수 있다. <code>?.</code>을 사용하면, 다음 추가 테스트를 피할 수 있다:</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">표현식에서 Optional chaining</h3>
<p>optional chaining 연산자를 속성에 표현식으로 접근할 때 대괄호 표기법(<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="Optional_chaining으로_배열_항목에_접근하기">Optional chaining으로 배열 항목에 접근하기</h3>
<pre class="brush: js">let arrayItem = arr?.[42];</pre>
<h2 id="예제">예제</h2>
<h3 id="기본_예제">기본 예제</h3>
<p>이 예제는 해당 멤버가 없을 때, map에서 멤버 bar의 <code>name</code>의 속성 값을 찾는다. 그러므로 결과는 <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="단락_평가">단락 평가</h3>
<p>표현식에서 optional chaining을 사용할 때, 만약 왼쪽에 있는 피연산자가 <code>null</code> or <code>undefined</code>인 경우, 그 표현식은 평가되지 않는다. 예들 들어:</p>
<pre class="brush: js">let potentiallyNullObj = null;
let x = 0;
let prop = potentiallyNullObj?.[x++];
console.log(x); // 0 x는 증가하지 않음
</pre>
<h3 id="optional_chaining_연산자_쌓기">optional chaining 연산자 쌓기</h3>
<p>중첩된 구조에서는 optional chaining을 여러 번 사용할 수 있다:</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="널_병합_연산자와_같이_사용하기">널 병합 연산자와 같이 사용하기</h3>
<p>널 병합 연산자는 optional chaining를 사용한 후에 아무 값도 찾을 수 없을 때 기본 값을 주기 위해 사용될 수 있다:</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="명세">명세</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="브라우저_호환성">브라우저 호환성</h2>
<p>{{Compat("javascript.operators.optional_chaining")}}</p>
<h2 id="참고">참고</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>
|