aboutsummaryrefslogtreecommitdiff
path: root/files/uk/web/javascript/reference/operators/destructuring_assignment/index.html
blob: 42936f43114c9d03e3c9faf769cdd755694331c5 (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
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
---
title: Деструктуризація
slug: Web/JavaScript/Reference/Operators/Destructuring_assignment
tags:
  - Destructuring
  - ECMAScript 2015
  - JavaScript
  - Operator
  - Деструктуризація
  - Оператор
translation_of: Web/JavaScript/Reference/Operators/Destructuring_assignment
original_slug: Web/JavaScript/Reference/Operators/Деструктуризація
---
<div>{{jsSidebar("Operators")}}</div>

<p><strong>Деструктуризація</strong> (деструктуризаційне присвоєння) - JavaScript вираз, який дозволяє витягувати дані з масивів та об’єктів в окремі змінні.</p>

<h2 id="Синтаксис">Синтаксис</h2>

<pre class="brush:js">var a, b, rest;
[a, b] = [10, 20];
console.log(a); // 10
console.log(b); // 20

[a, b, ...rest] = [10, 20, 30, 40, 50];
console.log(a); // 10
console.log(b); // 20
console.log(rest); // [30, 40, 50]

({a, b} = {a: 10, b: 20});
console.log(a); // 10
console.log(b); // 20

// Експерементальний синтаксис (ще не стандартизований)
({a, b, ...rest} = {a: 10, b: 20, c: 30, d: 40});
</pre>

<h2 id="Опис">Опис</h2>

<p>Вирази присвоєння літералів об’єктів та масивів надають простий спосіб створювати <em>ad hoc (ад-гок)</em> структури даних.</p>

<pre class="brush: js">var x = [1, 2, 3, 4, 5];</pre>

<p>Деструктуризаційне присвоєння використовує подібний синтаксис, де ліва сторона виразу визначає елементи, що потрібно витягнути зі змінної-джерела (правої сторони).</p>

<pre class="brush: js">var x = [1, 2, 3, 4, 5];
var [y, z] = x;
console.log(y); // 1
console.log(z); // 2
</pre>

<p>Це подібне до способів, що доступні у мовах програмування на кшталт Perl та Python.</p>

<h2 id="Деструктуризація_масивів">Деструктуризація масивів</h2>

<h3 id="Звичайне_присвоєння">Звичайне присвоєння</h3>

<pre class="brush: js">var foo = ['one', 'two', 'three'];

var [one, two, three] = foo;
console.log(one); // "one"
console.log(two); // "two"
console.log(three); // "three"
</pre>

<h3 id="Присвоєння_окреме_від_оголошення">Присвоєння, окреме від оголошення</h3>

<p>Значення може бути присвоєне змінній окремо від оголошення цієї змінної.</p>

<pre class="brush:js">var a, b;

[a, b] = [1, 2];
console.log(a); // 1
console.log(b); // 2
</pre>

<h3 id="Значення_за_промовчанням">Значення за промовчанням</h3>

<p>Змінній може бути присвоєне значення за промовчанням у випадку, коли витягнуте значення є <code>undefined</code>.</p>

<pre class="brush: js">var a, b;

[a=5, b=7] = [1];
console.log(a); // 1
console.log(b); // 7
</pre>

<h3 id="Обмін_змінних">Обмін змінних</h3>

<p>Дві змінні можуть обмінятися значеннями за допомогою одного деструктуризаційного виразу. </p>

<p>Без деструктуризації, обмін двох значеннь потребує тимчасової змінної (або в деяких низькорівневих мовах <a href="https://uk.wikipedia.org/wiki/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%BE%D0%B1%D0%BC%D1%96%D0%BD%D1%83_XOR">XOR-обміну</a>).</p>

<pre class="brush:js">var a = 1;
var b = 3;

[a, b] = [b, a];
console.log(a); // 3
console.log(b); // 1
</pre>

<h3 id="Розбір_масиву_поверненого_з_функції">Розбір масиву, поверненого з функції</h3>

<p>Завжди було можливо повернути масив із функції. Деструктуризація може зробити обробку повернутого масиву більш виразною.</p>

<p>У цьому прикладі <code>f()</code> повертає значення <code>[1, 2]</code>, які можуть бути розібрані одним рядком коду за допомогою деструктуризації.</p>

<pre class="brush:js">function f() {
  return [1, 2];
}

var a, b;
[a, b] = f();
console.log(a); // 1
console.log(b); // 2
</pre>

<h3 id="Пропуск_деяких_значень">Пропуск деяких значень</h3>

<p>Можна пропустити повернуті значення, які тобі не цікаві:</p>

<pre class="brush:js">function f() {
  return [1, 2, 3];
}

var [a, , b] = f();
console.log(a); // 1
console.log(b); // 3
</pre>

<p>Також можна пропустити всі значення (але навіщо?):</p>

<pre class="brush:js">[,,] = f();
</pre>

<h3 id="Присвоєння_решти_масиву_змінній">Присвоєння решти масиву змінній</h3>

<p>Деструктуризуючи масив, можна присвоїти змінній решту його елементів за допомогою <a href="/uk/docs/Web/JavaScript/Reference/Operators/%D0%9E%D0%BF%D0%B5%D1%80%D0%B0%D1%82%D0%BE%D1%80_%D1%80%D0%BE%D0%B7%D0%BF%D0%B0%D0%BA%D1%83%D0%B2%D0%B0%D0%BD%D0%BD%D1%8F">оператора розпакування</a>:</p>

<pre class="brush: js">var [a, ...b] = [1, 2, 3];
console.log(a); // 1
console.log(b); // [2, 3]</pre>

<p>Зауваж, що буде видана помилка {{jsxref("SyntaxError")}}, якщо поставити прикінцеву кому в лівій частині виразу за елементом решти:</p>

<pre class="brush: js example-bad">var [a, ...b,] = [1, 2, 3];
// SyntaxError: елемент решти не може мати прикінцевої коми</pre>

<h3 id="Витягнення_значеннь_з_масиву_збігів_регулярного_виразу">Витягнення значеннь з масиву збігів регулярного виразу</h3>

<p>Коли метод регулярного виразу <code><a href="/uk/docs/Web/JavaScript/Reference/Global_Objects/RegExp/exec">exec()</a></code> знаходить збіг, він повертає масив, що містить першим елементом повністю відповідну частину рядку, а далі частини рядку, що збіглися з кожною взятою в дужки групою в регулярному виразі. Деструктуризаційне присвоєння дозволяє з легкістю витягувати частини цього масиву, пропускаючи повний збіг, якщо він не потрібний.</p>

<pre class="brush:js">var url = 'https://developer.mozilla.org/en-US/Web/JavaScript';

var parsedURL = /^(\w+)\:\/\/([^\/]+)\/(.*)$/.exec(url);
console.log(parsedURL); // ["https://developer.mozilla.org/en-US/Web/JavaScript", "https", "developer.mozilla.org", "en-US/Web/JavaScript"]

var [, protocol, fullhost, fullpath] = parsedURL;

console.log(protocol); // "https"
</pre>

<h2 id="Деструктуризація_об’єктів">Деструктуризація об’єктів</h2>

<h3 id="Звичайне_присвоєння_2">Звичайне присвоєння</h3>

<pre class="brush: js">var o = {p: 42, q: true};
var {p, q} = o;

console.log(p); // 42
console.log(q); // true
</pre>

<h3 id="Присвоєння_окреме_від_оголошення_2">Присвоєння, окреме від оголошення</h3>

<p>Значення може бути присвоєне змінній окремо від оголошення цієї змінної.</p>

<pre class="brush:js">var a, b;

({a, b} = {a: 1, b: 2});</pre>

<div class="note">
<p>Дужки <code>( .. )</code> навколо виразу присвоєння необхідні при деструктуризаційному присвоєні об’єкта без оголошення.</p>

<p>Вираз <code>{a, b} = {a: 1, b: 2}</code> сам по собі є синтаксично неправильним, оскільки <code>{a, b}</code> в лівій його частині розглядається як блок коду, а не як об’єкт.</p>

<p>Проте, <code>({a, b} = {a: 1, b: 2})</code> є правильним, як і <code>var {a, b} = {a: 1, b: 2}</code></p>
</div>

<h3 id="Присвоєння_новим_змінним">Присвоєння новим змінним</h3>

<p>Значення може бути отримане з об’єкту та присвоєне змінній з іменем, інакшим від назви властивості об’єкта.</p>

<pre class="brush: js">var o = {p: 42, q: true};
var {p: foo, q: bar} = o;

console.log(foo); // 42
console.log(bar); // true  </pre>

<h3 id="Значення_за_промовчанням_2">Значення за промовчанням</h3>

<p>Змінній може бути присвоєне значення за промовчанням у випадку, коли витягнуте значення з об’єкту є <code>undefined</code>.</p>

<pre class="brush: js">var {a = 10, b = 5} = {a: 3};

console.log(a); // 3
console.log(b); // 5</pre>

<h3 id="Встановлення_значення_за_промовчанням_аргументам_функції">Встановлення значення за промовчанням аргументам функції</h3>

<h4 id="ES5_версія">ES5 версія</h4>

<pre class="brush: js">function drawES5Chart(options) {
  options = options === undefined ? {} : options;
  var size = options.size === undefined ? 'big' : options.size;
  var cords = options.cords === undefined ? {x: 0, y: 0} : options.cords;
  var radius = options.radius === undefined ? 25 : options.radius;
  console.log(size, cords, radius);
  // тепер, врешті, малюй діаграму
}

drawES5Chart({
  cords: {x: 18, y: 30},
  radius: 30
});</pre>

<h4 id="ES2015_версія">ES2015 версія</h4>

<pre class="brush: js">function drawES2015Chart({size = 'big', cords = {x: 0, y: 0}, radius = 25} = {}) {
  console.log(size, cords, radius);
  // малюй діаграму
}

drawES2015Chart({
  cords: {x: 18, y: 30},
  radius: 30
});</pre>

<h3 id="Вкладена_деструктуризація_об’єктів_та_масивів">Вкладена деструктуризація об’єктів та масивів</h3>

<pre class="brush:js">var metadata = {
    title: 'Scratchpad',
    translations: [
       {
        locale: 'de',
        localization_tags: [],
        last_edit: '2014-04-14T08:43:37',
        url: '/de/docs/Tools/Scratchpad',
        title: 'JavaScript-Umgebung'
       }
    ],
    url: '/en-US/docs/Tools/Scratchpad'
};

var {title: englishTitle, translations: [{title: localeTitle}]} = metadata;

console.log(englishTitle); // "Scratchpad"
console.log(localeTitle);  // "JavaScript-Umgebung"</pre>

<h3 id="For_of_цикл_та_деструктуризація">For of цикл та деструктуризація</h3>

<pre class="brush: js">var people = [
  {
    name: 'Mike Smith',
    family: {
      mother: 'Jane Smith',
      father: 'Harry Smith',
      sister: 'Samantha Smith'
    },
    age: 35
  },
  {
    name: 'Tom Jones',
    family: {
      mother: 'Norah Jones',
      father: 'Richard Jones',
      brother: 'Howard Jones'
    },
    age: 25
  }
];

for (var {name: n, family: {father: f}} of people) {
  console.log('Name: ' + n + ', Father: ' + f);
}

// "Name: Mike Smith, Father: Harry Smith"
// "Name: Tom Jones, Father: Richard Jones"</pre>

<h3 id="Витягнення_полів_з_об’єктів_що_передані_аргументами_в_функцію">Витягнення полів з об’єктів, що передані аргументами в функцію</h3>

<pre class="brush:js">function userId({id}) {
  return id;
}

function whois({displayName, fullName: {firstName: name}}) {
  console.log(displayName + ' is ' + name);
}

var user = {
  id: 42,
  displayName: 'jdoe',
  fullName: {
      firstName: 'John',
      lastName: 'Doe'
  }
};

console.log('userId: ' + userId(user)); // "userId: 42"
whois(user); // "jdoe is John"</pre>

<p>Це витягує <code>id</code>, <code>displayName</code> та <code>firstName</code> з об’єкта <font face="Consolas, Liberation Mono, Courier, monospace">user</font> та виводить їх.</p>

<h3 id="Розраховувані_імена_властивостей_об’єкта_та_деструктуризація">Розраховувані імена властивостей об’єкта та деструктуризація</h3>

<p><a href="/uk/docs/Web/JavaScript/Reference/Operators/Ініціалізація_об’єктів#Розраховувані_імена_властивостей">Розраховувані імена властивостей</a> об’єкта можуть також бути використані разом із деструктуризацією</p>

<pre class="brush: js">let key = 'z';
let {[key]: foo} = {z: 'bar'};

console.log(foo); // "bar"
</pre>

<h2 id="Специфікації">Специфікації</h2>

<table class="standard-table">
 <tbody>
  <tr>
   <th scope="col">Specification</th>
   <th scope="col">Status</th>
   <th scope="col">Comment</th>
  </tr>
  <tr>
   <td>{{SpecName('ES2015', '#sec-destructuring-assignment', 'Destructuring assignment')}}</td>
   <td>{{Spec2('ES2015')}}</td>
   <td>Initial definition.</td>
  </tr>
  <tr>
   <td>{{SpecName('ESDraft', '#sec-destructuring-assignment', 'Destructuring assignment')}}</td>
   <td>{{Spec2('ESDraft')}}</td>
   <td> </td>
  </tr>
 </tbody>
</table>

<h2 id="Сумісність_з_браузерами">Сумісність з браузерами </h2>

<div>{{CompatibilityTable}}</div>

<div id="compat-desktop">
<table class="compat-table">
 <tbody>
  <tr>
   <th>Feature</th>
   <th>Chrome</th>
   <th>Firefox (Gecko)</th>
   <th>Edge</th>
   <th>Internet Explorer</th>
   <th>Opera</th>
   <th>Safari</th>
  </tr>
  <tr>
   <td>Basic support</td>
   <td>{{CompatChrome(49.0)}}</td>
   <td>{{ CompatGeckoDesktop("1.8.1") }}</td>
   <td>14</td>
   <td>{{CompatNo}}</td>
   <td>{{CompatNo}}</td>
   <td>7.1</td>
  </tr>
  <tr>
   <td>Computed property names</td>
   <td>{{CompatChrome(49.0)}}</td>
   <td>{{ CompatGeckoDesktop("34") }}</td>
   <td>14</td>
   <td>{{CompatNo}}</td>
   <td>{{CompatNo}}</td>
   <td>{{CompatNo}}</td>
  </tr>
  <tr>
   <td>Spread operator</td>
   <td>{{CompatChrome(49.0)}}</td>
   <td>{{ CompatGeckoDesktop("34") }}</td>
   <td>12<sup>[1]</sup></td>
   <td>{{CompatUnknown}}</td>
   <td>{{CompatUnknown}}</td>
   <td>{{CompatUnknown}}</td>
  </tr>
 </tbody>
</table>
</div>

<div id="compat-mobile">
<table class="compat-table">
 <tbody>
  <tr>
   <th>Feature</th>
   <th>Android</th>
   <th>Chrome for Android</th>
   <th>Firefox Mobile (Gecko)</th>
   <th>IE Mobile</th>
   <th>Opera Mobile</th>
   <th>Safari Mobile</th>
   <th>Chrome for Android</th>
  </tr>
  <tr>
   <td>Basic support</td>
   <td>{{CompatNo}}</td>
   <td>{{CompatChrome(49.0)}}</td>
   <td>{{ CompatGeckoMobile("1.0") }}</td>
   <td>{{CompatNo}}</td>
   <td>{{CompatNo}}</td>
   <td>8</td>
   <td>{{CompatChrome(49.0)}}</td>
  </tr>
  <tr>
   <td>Computed property names</td>
   <td>{{CompatNo}}</td>
   <td>{{CompatChrome(49.0)}}</td>
   <td>{{ CompatGeckoMobile("34") }}</td>
   <td>{{CompatNo}}</td>
   <td>{{CompatNo}}</td>
   <td>{{CompatNo}}</td>
   <td>{{CompatChrome(49.0)}}</td>
  </tr>
  <tr>
   <td>Spread operator</td>
   <td>{{CompatNo}}</td>
   <td>{{CompatChrome(49.0)}}</td>
   <td>{{ CompatGeckoMobile("34") }}</td>
   <td>{{CompatUnknown}}</td>
   <td>{{CompatUnknown}}</td>
   <td>{{CompatUnknown}}</td>
   <td>{{CompatChrome(49.0)}}</td>
  </tr>
 </tbody>
</table>
</div>

<p>[1] Потребує ввімкнення "Enable experimental Javascript features" в налаштуваннях `about:flags`</p>

<h2 id="Примітки_для_Firefox">Примітки для Firefox</h2>

<ul>
 <li>Firefox надавав нестандартне розширення мови в <a href="/en-US/docs/Web/JavaScript/New_in_JavaScript/1.7">JS1.7</a> для деструктуризації. Це розширення було видалене в Gecko 40 {{geckoRelease(40)}}. Дивись {{bug(1083498)}}.</li>
 <li>Починаючи від Gecko 41 {{geckoRelease(41)}} та згідно зі спецефікацією ES2015, деструктуризаціїні вирази в дужках, на кшталт <code>([a, b]) = [1, 2]</code> or <code>({a, b}) = { a: 1, b: 2 }</code>, зараз вважаються неправильними та будуть видавати помилку {{jsxref("SyntaxError")}}. Дивись <a class="external external-icon" href="http://whereswalden.com/2015/06/20/new-changes-to-make-spidermonkeys-and-firefoxs-parsing-of-destructuring-patterns-more-spec-compliant/">Jeff Walden's blog post</a> та {{bug(1146136)}} щоб довідатись більше.</li>
</ul>

<h2 id="Дивись_також">Дивись також</h2>

<ul>
 <li><a href="/uk/docs/Web/JavaScript/Reference/Operators/%D0%9E%D0%BF%D0%B5%D1%80%D0%B0%D1%82%D0%BE%D1%80%D0%B8_%D0%BF%D1%80%D0%B8%D1%81%D0%B2%D0%BE%D1%94%D0%BD%D0%BD%D1%8F">Оператори присвоєння</a></li>
 <li><a href="https://hacks.mozilla.org/2015/05/es6-in-depth-destructuring/">"ES6 in Depth: Destructuring" on hacks.mozilla.org</a></li>
</ul>