aboutsummaryrefslogtreecommitdiff
path: root/files/ar/web/javascript/reference/operators/destructuring_assignment/index.html
blob: d926351173d951cb23897096c2c97124ef4f7671 (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
---
title: Destructuring assignment
slug: Web/JavaScript/Reference/Operators/Destructuring_assignment
translation_of: Web/JavaScript/Reference/Operators/Destructuring_assignment
---
<div>{{jsSidebar("Operators")}}</div>

<div dir="rtl"><strong>الإسناد بالتفكيك</strong> هو تعبير جافاسكربت يجعل من الممكن فك القيم من المصفوفات ( Arrays ) أو الخصائص من الكائنات ( Objects ) إلى متغيرات مميزة.</div>

<div dir="rtl"></div>

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

<div class="hidden">The source for this interactive example is stored in a GitHub repository. If you'd like to contribute to the interactive examples project, please clone <a href="https://github.com/mdn/interactive-examples">https://github.com/mdn/interactive-examples</a> and send us a pull request.</div>

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

<pre class="brush:js">let 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


// Stage 4(finished) proposal
({a, b, ...rest} = {a: 10, b: 20, c: 30, d: 40});
console.log(a); // 10
console.log(b); // 20
console.log(rest); // {c: 30, d: 40}
</pre>

<h2 dir="rtl" id="التفاصيل">التفاصيل</h2>

<p dir="rtl">توفر تعبيرات الكائن (Object) والمصفوفة (Array) طريقة سهلة لإنشاء حزم بيانات مخصصة.</p>

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

<p dir="rtl" id="tw-target-text">يَستخدِم<strong> الإسناد بالتفكيك (destructuring assignment)</strong> بنية مماثلة، ولكن على الجانب الأيسر من المهمة لتحديد القيم التي يجب فكها من مصدر المتغير الأساسي.</p>

<pre dir="rtl" id="tw-target-text">const x = [1, 2, 3, 4, 5];
const [y, z] = x;
console.log(y); // 1
console.log(z); // 2
</pre>

<p dir="rtl">تشبه هذه الإمكانية الميزات الموجودة بلغات مثل Perl و Python.</p>

<p dir="rtl"></p>

<h2 dir="rtl" id="تفكيك_المصفوفات">تفكيك المصفوفات</h2>

<h3 dir="rtl" id="تعيين_المتغير_الأساسي">تعيين المتغير الأساسي</h3>

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

const [red, yellow, green] = foo;
console.log(red); // "one"
console.log(yellow); // "two"
console.log(green); // "three"
</pre>

<h3 id="Assignment_separate_from_declaration">Assignment separate from declaration</h3>

<p>A variable can be assigned its value via destructuring separate from the variable's declaration.</p>

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

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

<h3 id="Default_values">Default values</h3>

<p>A variable can be assigned a default, in the case that the value unpacked from the array is <code>undefined</code>.</p>

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

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

<h3 id="Swapping_variables">Swapping variables</h3>

<p>Two variables values can be swapped in one destructuring expression.</p>

<p>Without destructuring assignment, swapping two values requires a temporary variable (or, in some low-level languages, the <a class="external" href="https://en.wikipedia.org/wiki/XOR_swap_algorithm">XOR-swap trick</a>).</p>

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

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

const arr = [1,2,3];
[arr[2], arr[1]] = [arr[1], arr[2]];
console.log(arr); // [1,3,2]

</pre>

<h3 id="Parsing_an_array_returned_from_a_function">Parsing an array returned from a function</h3>

<p>It's always been possible to return an array from a function. Destructuring can make working with an array return value more concise.</p>

<p>In this example, <code>f()</code> returns the values <code>[1, 2]</code> as its output, which can be parsed in a single line with destructuring.</p>

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

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

<h3 id="Ignoring_some_returned_values">Ignoring some returned values</h3>

<p>You can ignore return values that you're not interested in:</p>

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

const [a, , b] = f();
console.log(a); // 1
console.log(b); // 3

const [c] = f();
console.log(c); // 1
</pre>

<p>You can also ignore all returned values:</p>

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

<h3 id="Assigning_the_rest_of_an_array_to_a_variable">Assigning the rest of an array to a variable</h3>

<p>When destructuring an array, you can unpack and assign the remaining part of it to a variable using the rest pattern:</p>

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

<p>Be aware that a {{jsxref("SyntaxError")}} will be thrown if a trailing comma is used on the left-hand side with a rest element:</p>

<pre class="brush: js example-bad">const [a, ...b,] = [1, 2, 3];

// SyntaxError: rest element may not have a trailing comma
// Always consider using rest operator as the last element
</pre>

<h3 id="Unpacking_values_from_a_regular_expression_match">Unpacking values from a regular expression match</h3>

<p>When the regular expression <code><a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp/exec"> exec()</a></code> method finds a match, it returns an array containing first the entire matched portion of the string and then the portions of the string that matched each parenthesized group in the regular expression. Destructuring assignment allows you to unpack the parts out of this array easily, ignoring the full match if it is not needed.</p>

<pre class="brush:js">function parseProtocol(url) {
  const parsedURL = /^(\w+)\:\/\/([^\/]+)\/(.*)$/.exec(url);
  if (!parsedURL) {
    return false;
  }
  console.log(parsedURL); // ["https://developer.mozilla.org/en-US/Web/JavaScript", "https", "developer.mozilla.org", "en-US/Web/JavaScript"]

  const [, protocol, fullhost, fullpath] = parsedURL;
  return protocol;
}

console.log(parseProtocol('https://developer.mozilla.org/en-US/Web/JavaScript')); // "https"
</pre>

<h2 id="Object_destructuring">Object destructuring</h2>

<h3 id="Basic_assignment">Basic assignment</h3>

<pre class="brush: js">const user = {
    id: 42,
    is_verified: true
};

const {id, is_verified} = user;

console.log(id); // 42
console.log(is_verified); // true
</pre>

<h3 id="Assignment_without_declaration">Assignment without declaration</h3>

<p>A variable can be assigned its value with destructuring separate from its declaration.</p>

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

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

<div class="note">
<p><strong>Notes</strong>: The parentheses <code>( ... )</code> around the assignment statement are required when using object literal destructuring assignment without a declaration.</p>

<p><code>{a, b} = {a: 1, b: 2}</code> is not valid stand-alone syntax, as the <code>{a, b}</code> on the left-hand side is considered a block and not an object literal.</p>

<p>However, <code>({a, b} = {a: 1, b: 2})</code> is valid, as is <code>const {a, b} = {a: 1, b: 2}</code></p>

<p>Your <code>( ... )</code> expression needs to be preceded by a semicolon or it may be used to execute a function on the previous line.</p>
</div>

<h3 id="Assigning_to_new_variable_names">Assigning to new variable names</h3>

<p>A property can be unpacked from an object and assigned to a variable with a different name than the object property.</p>

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

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

<p>Here, for example, <code>const {p: foo} = o</code> takes from the object <code>o</code> the property named <code>p</code> and assigns it to a local variable named <code>foo</code>.</p>

<h3 id="Default_values_2">Default values</h3>

<p>A variable can be assigned a default, in the case that the value unpacked from the object is <code>undefined</code>.</p>

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

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

<h3 id="Assigning_to_new_variables_names_and_providing_default_values">Assigning to new variables names and providing default values</h3>

<p>A property can be both 1) unpacked from an object and assigned to a variable with a different name and 2) assigned a default value in case the unpacked value is <code>undefined</code>.</p>

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

console.log(aa); // 3
console.log(bb); // 5
</pre>

<h3 id="Unpacking_fields_from_objects_passed_as_function_parameter">Unpacking fields from objects passed as function parameter</h3>

<pre class="brush:js">const user = {
  id: 42,
  displayName: 'jdoe',
  fullName: {
    firstName: 'John',
    lastName: 'Doe'
  }
};

function userId({id}) {
  return id;
}

function whois({displayName, fullName: {firstName: name}}) {
  return `${displayName} is ${name}`;
}

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

<p>This unpacks the <code>id</code>, <code>displayName</code> and <code>firstName</code> from the user object and prints them.</p>

<h3 id="Setting_a_function_parameters_default_value">Setting a function parameter's default value</h3>

<pre class="brush: js">function drawChart({size = 'big', coords = {x: 0, y: 0}, radius = 25} = {}) {
  console.log(size, coords, radius);
  // do some chart drawing
}

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

<div class="note">
<p>In the function signature for <strong><code>drawChart</code></strong> above, the destructured left-hand side is assigned to an empty object literal on the right-hand side: <code>{size = 'big', coords = {x: 0, y: 0}, radius = 25} = {}</code>. You could have also written the function without the right-hand side assignment. However, if you leave out the right-hand side assignment, the function will look for at least one argument to be supplied when invoked, whereas in its current form, you can simply call <code><strong>drawChart()</strong></code> without supplying any parameters. The current design is useful if you want to be able to call the function without supplying any parameters, the other can be useful when you want to ensure an object is passed to the function.</p>
</div>

<h3 id="Nested_object_and_array_destructuring">Nested object and array destructuring</h3>

<pre class="brush:js">const 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'
};

let {
  title: englishTitle, // rename
  translations: [
    {
       title: localeTitle, // rename
    },
  ],
} = metadata;

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

<h3 id="For_of_iteration_and_destructuring">For of iteration and destructuring</h3>

<pre class="brush: js">const 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 (const {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="Computed_object_property_names_and_destructuring">Computed object property names and destructuring</h3>

<p>Computed property names, like on <a href="/en-US/docs/Web/JavaScript/Reference/Operators/Object_initializer#Computed_property_names">object literals</a>, can be used with destructuring.</p>

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

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

<h3 id="Rest_in_Object_Destructuring">Rest in Object Destructuring</h3>

<p>The <a class="external external-icon" href="https://github.com/tc39/proposal-object-rest-spread">Rest/Spread Properties for ECMAScript</a> proposal (stage 4) adds the <a href="/en-US/docs/Web/JavaScript/Reference/Functions/rest_parameters">rest</a> syntax to destructuring. Rest properties collect the remaining own enumerable property keys that are not already picked off by the destructuring pattern.</p>

<pre class="brush: js">let {a, b, ...rest} = {a: 10, b: 20, c: 30, d: 40}
a; // 10
b; // 20
rest; // { c: 30, d: 40 }</pre>

<h3 id="Invalid_JavaScript_identifier_as_a_property_name">Invalid JavaScript identifier as a property name</h3>

<p>Destructuring can be used with property names that are not valid JavaScript {{glossary("Identifier", "identifiers")}} by providing an alternative identifier that is valid.</p>

<pre class="brush: js">const foo = { 'fizz-buzz': true };
const { 'fizz-buzz': fizzBuzz } = foo;

console.log(fizzBuzz); // "true"
</pre>

<h3 id="Combined_Array_and_Object_Destructuring">Combined Array and Object Destructuring</h3>

<p>Array and Object destructuring can be combined. Say you want the third element in the array <code>props</code> below, and then you want the <code>name</code> property in the object, you can do the following:</p>

<pre class="brush: js">const props = [
  { id: 1, name: 'Fizz'},
  { id: 2, name: 'Buzz'},
  { id: 3, name: 'FizzBuzz'}
];

const [,, { name }] = props;

console.log(name); // "FizzBuzz"
</pre>

<h3 id="The_prototype_chain_is_looked_up_when_the_object_is_deconstructed">The prototype chain is looked up when the object is deconstructed </h3>

<p>When deconstructing an object, if a property is not accessed in itself, it will continue to look up along the prototype chain.</p>

<pre class="brush: js">let obj = {self: '123'};
obj.__proto__.prot = '456';
const {self, prot} = obj;
// self "123"
// prot "456"(Access to the prototype chain)</pre>

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

<table class="standard-table">
 <thead>
  <tr>
   <th scope="col">Specification</th>
  </tr>
 </thead>
 <tbody>
  <tr>
   <td>{{SpecName('ESDraft', '#sec-destructuring-assignment', 'Destructuring assignment')}}</td>
  </tr>
 </tbody>
</table>

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

<div>


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

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

<ul>
 <li><a href="/en-US/docs/Web/JavaScript/Reference/Operators/Assignment_Operators">Assignment operators</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>