diff options
author | Peter Bengtsson <mail@peterbe.com> | 2020-12-08 14:42:52 -0500 |
---|---|---|
committer | Peter Bengtsson <mail@peterbe.com> | 2020-12-08 14:42:52 -0500 |
commit | 074785cea106179cb3305637055ab0a009ca74f2 (patch) | |
tree | e6ae371cccd642aa2b67f39752a2cdf1fd4eb040 /files/ru/web/javascript/reference/operators/optional_chaining | |
parent | da78a9e329e272dedb2400b79a3bdeebff387d47 (diff) | |
download | translated-content-074785cea106179cb3305637055ab0a009ca74f2.tar.gz translated-content-074785cea106179cb3305637055ab0a009ca74f2.tar.bz2 translated-content-074785cea106179cb3305637055ab0a009ca74f2.zip |
initial commit
Diffstat (limited to 'files/ru/web/javascript/reference/operators/optional_chaining')
-rw-r--r-- | files/ru/web/javascript/reference/operators/optional_chaining/index.html | 176 |
1 files changed, 176 insertions, 0 deletions
diff --git a/files/ru/web/javascript/reference/operators/optional_chaining/index.html b/files/ru/web/javascript/reference/operators/optional_chaining/index.html new file mode 100644 index 0000000000..30fd29e3c0 --- /dev/null +++ b/files/ru/web/javascript/reference/operators/optional_chaining/index.html @@ -0,0 +1,176 @@ +--- +title: "Оператор\_опциональной последовательности" +slug: Web/JavaScript/Reference/Operators/Optional_chaining +translation_of: Web/JavaScript/Reference/Operators/Optional_chaining +--- +<div>{{jsSidebar("Operators")}}</div> + +<p>Оператор <strong>опциональной последовательности</strong> <strong><code>?.</code></strong> позволяет получить значение свойства, находящегося на любом уровне вложенности в цепочке связанных между собой объектов, без необходимости проверять каждое из промежуточных свойств в ней на существование. <span class="seoSummary"> <code>?.</code> работает подобно оператору <code>.</code>, за исключением того, что не выбрасывает исключение, если объект, к свойству или методу которого идёт обращение, равен {{jsxref("null")}} или {{jsxref("undefined")}}. В этих случаях он возвращает <code>undefined</code>.</span></p> + +<p>Таким образом, мы получаем более короткий и понятный код при обращении к вложенным по цепочке свойствам объекта, когда есть вероятность, что какое-то из них отсутствует.</p> + +<div>{{EmbedInteractiveExample("pages/js/expressions-optionalchainingoperator.html", "taller")}}</div> + +<div></div> + + + +<h2 id="Синтаксис">Синтаксис</h2> + +<pre class="syntaxbox"><var>obj</var>?.<var>prop</var> +<var>obj</var>?.[<var>expr</var>] +arr?.[index] +<var>func</var>?.(<var>args</var>) +</pre> + +<h2 id="Описание">Описание</h2> + +<p>Оператор опциональной последовательности предоставляет способ упростить доступ к значениям в цепочке обьектов, когда возможно, что какое-то свойство (или метод) в ней равно <code>undefined</code> или <code>null</code>.</p> + +<p>Для примера, создадим обьект <code>obj</code>, имеющий вложенную структуру. Без оператора опциональной последовательности поиск глубоко расположенных подсвойств требует проверки всех промежуточных свойств на существование, например:</p> + +<pre class="brush: js">let nestedProp = obj.first && obj.first.second;</pre> + +<p>Если обращаться к <code>obj.first.second</code> без проверки <code>obj.first</code>, то, если свойство <code>obj.first</code> равно <code>null</code> или <code>undefined</code>, выбросится исключение {{jsxref("TypeError")}}.</p> + +<p>Однако, с оператором опциональной последовательности (<code>?.</code>) не требуется явно проверять ссылку на <code>obj.first</code> перед обращением к <code>obj.first.second</code>:</p> + +<pre class="brush: js">let nestedProp = obj.first?.second;</pre> + +<p>Если используется оператор <code>?.</code> вместо <code>.</code>, JavaScript знает о необходимости проверки <code>obj.first</code> перед обращением к <code>obj.first.second</code>. Если значение <code>obj.first</code> равно <code>null</code> или <code>undefined</code>, выполнение выражения автоматически прекращается и возвращается <code>undefined</code>.</p> + +<p>Это эквивалентно следующему (кроме создания временной переменной):</p> + +<pre>let temp = obj.first; +let nestedProp = ((temp === null || temp === undefined) ? undefined : temp.second);</pre> + +<h3 id="Опциональная_последовательность_с_вызовом_функции">Опциональная последовательность с вызовом функции</h3> + +<p>Вы можете использовать <code>?.</code><strong>, </strong>когда необходимо вызвать метод, которого может не существовать. Это может быть полезно, например, при использовании API, в котором метод может быть недоступен из-за устаревания или неподдерживаемости устройством пользователя.</p> + +<p>Использование <code>?.</code><strong> </strong>с вызовом функции значит, что выполнение автоматически вернет <code>undefined</code>, а не выбросит исключение, если метод не найден:</p> + +<pre class="brush: js">let result = someInterface.customMethod?.();</pre> + +<div class="blockIndicator note"> +<p><strong>Обратите внимание:</strong> Для существующего свойства, не являющегося функцией, использование конструкции <code>x.y?.()</code> всё равно выбросит {{jsxref("TypeError")}} исключение (<code>x.y не является функцией</code>).</p> +</div> + +<h3 id="Работа_с_функциями_обратного_вызова_и_обработчиками_событий">Работа с функциями обратного вызова и обработчиками событий</h3> + +<p>Если Вы используете функции обратного вызова или извлекаете методы обьекта <a href="/ru/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment#Разбор_объектов">деструктурирующим присваиванием</a>, Вы можете получить несуществующие значения, которые нельзя вызывать как функции до проверки на их существование. Используя оператор <code>?.</code>, Вы можете избежать лишних проверок:</p> + +<pre class="brush: js">// С использованием ES2019 +function doSomething(onContent, onError) { + try { + // ... делаем что-то с данными + } + catch (err) { + if (onError) { // проверяем, существует ли onError + onError(err.message); + } + } +}</pre> + +<pre class="brush: js">// С использованием оператора опциональной последовательности +function doSomething(onContent, onError) { + try { + // ... делаем что-то с данными + } + catch (err) { + onError?.(err.message); // не выбросит исключение, если onError равен undefined + } +} +</pre> + +<h3 id="Опциональные_последовательности_в_выражениях">Опциональные последовательности в выражениях</h3> + +<p>Вы также можете использовать оператор опциональной последовательности, когда обращаетесь к свойству с помощью <a href="/ru/docs/Web/JavaScript/Reference/Operators/Property_Accessors#Скобочная_нотация">скобочной нотации</a>:</p> + +<pre class="brush: js">let nestedProp = obj?.['prop' + 'Name']; +</pre> + +<h2 id="Примеры">Примеры</h2> + +<h3 id="Базовый_пример">Базовый пример</h3> + +<p>В этом примере производится обращение к свойству <code>name</code> элемента с ключом <code>bar</code> объекта <code>Map</code>. Элемент с таким ключом отсутствует, но исключение выброшено не будет; <code>nameBar</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>При использовании оператора опциональной последовательности в выражениях, где левая часть операнда равна <code>null</code> или <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="Совместное_использование_операторов_опциональной_последовательности">Совместное использование операторов опциональной последовательности</h3> + +<p>Во вложенных объектах возможно использование оператора опциональной последовательности неограниченное количество раз:</p> + +<pre class="brush: js">let customer = { + name: "Carl", + details: { + age: 82, + location: "Paradise Falls" // точный адрес неизвестен + } +}; +let customerCity = customer.details?.address?.city; + +// … это также работает с вызовами функций +let duration = vacations.trip?.getTime?.(); +</pre> + +<h3 id="Использование_с_оператором">Использование с оператором ??</h3> + +<p>Оператор {{JSxRef("Operators/Nullish_Coalescing_Operator", "??", '', 1)}} может использоваться после опциональной последовательности для установления значения по умолчанию:</p> + +<pre>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">Спецификация</th> + <th scope="col">Статус</th> + <th scope="col">Примечание</th> + </tr> + </thead> + <tbody> + <tr> + <td><a href="https://tc39.es/proposal-optional-chaining/">Proposal for the "optional chaining" operator</a></td> + <td>Stage 4</td> + <td></td> + </tr> + </tbody> +</table> + +<h2 id="Совместимость_с_браузерами">Совместимость с браузерами</h2> + +<div> + + +<p>{{Compat("javascript.operators.optional_chaining")}}</p> +</div> + +<h2 id="Смотрите_также">Смотрите также</h2> + +<ul> + <li><a href="https://github.com/tc39/proposal-pipeline-operator">Github - Proposal-pipeline-operator</a></li> + <li><a href="https://github.com/tc39/proposals">TC39 proposals</a></li> + <li>{{JSxRef("Operators/Nullish_Coalescing_Operator", "Nullish Coalescing Operator", '', 1)}}</li> +</ul> |