aboutsummaryrefslogtreecommitdiff
path: root/files/ja/web/javascript/reference/operators/destructuring_assignment/index.html
blob: 13aade654e1765332771396b2f8ef4ba2836ff66 (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
---
title: 分割代入
slug: Web/JavaScript/Reference/Operators/Destructuring_assignment
tags:
  - Destructuring
  - Destructuring_assignment
  - ECMAScript 2015
  - ES6
  - JavaScript
  - Language feature
  - Nested object and array destructuring
  - Operator
  - 分割代入
  - 演算子
translation_of: Web/JavaScript/Reference/Operators/Destructuring_assignment
---
<div>{{jsSidebar("Operators")}}</div>

<p><strong>分割代入</strong> (Destructuring assignment) 構文は、配列から値を取り出して、あるいはオブジェクトからプロパティを取り出して別個の変数に代入することを可能にする JavaScript の式です。</p>

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

<div class="hidden">このデモのソースファイルは GitHub リポジトリに格納されています。デモプロジェクトに協力したい場合は、<a href="https://github.com/mdn/interactive-examples">https://github.com/mdn/interactive-examples</a> をクローンしてプルリクエストを送信してください。</div>

<h2 id="Syntax" name="Syntax">構文</h2>

<pre class="brush:js notranslate">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 id="Description" name="Description">解説</h2>

<p>オブジェクトリテラルと配列リテラルは、いくつかのデータを<em>アドホック</em>にまとめる簡単な方法を提供します。</p>

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

<p>分割代入は似たような構文を使用しますが、代入の左辺が元の変数からどの値を受け取るかを定義します。</p>

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

<p>この機能は、Perl や Python などの言語に存在する機能に似ています。</p>

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

<h3 id="Array_destructuring" name="Array_destructuring">配列の分割代入</h3>

<h4 id="Basic_variable_assignment" name="Basic_variable_assignment">簡単な例</h4>

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

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

<h4 id="Assignment_separate_from_declaration" name="Assignment_separate_from_declaration">宣言後の割り当て</h4>

<p>変数は宣言とは別に、分割代入によって値を代入することができます。</p>

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

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

<h4 id="Default_values" name="Default_values">既定値</h4>

<p>配列から取り出した値が <code>undefined</code> だった場合に使用される既定値を指定できます。</p>

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

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

<h4 id="Swapping_variables" name="Swapping_variables">変数の入れ替え</h4>

<p>分割代入を使用して、複数の変数の値を入れ替えることができます。</p>

<p>分割代入を使用せずに 2 つの値を交換するには、一時変数 (または、一部の低水準言語においては <a href="https://ja.wikipedia.org/wiki/XOR%E4%BA%A4%E6%8F%9B%E3%82%A2%E3%83%AB%E3%82%B4%E3%83%AA%E3%82%BA%E3%83%A0">XOR 交換アルゴリズム</a>) が必要です。</p>

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

<h4 id="Parsing_an_array_returned_from_a_function" name="Parsing_an_array_returned_from_a_function">関数から返された配列の解析</h4>

<p>関数は配列を返すことができます。分割代入によって、返された配列の使用をより簡潔に記述できます。</p>

<p>この例では、<code>f()</code> は出力として値 <code>[1, 2]</code> を返しており、分割代入により 1行で解析できます。</p>

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

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

<h4 id="Ignoring_some_returned_values" name="Ignoring_some_returned_values">返値の無視</h4>

<p>関心のない返値は無視することができます。</p>

<pre class="brush:js notranslate">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>このようにすべての返値を無視することもできます。</p>

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

<h4 id="Assigning_the_rest_of_an_array_to_a_variable" name="Assigning_the_rest_of_an_array_to_a_variable">配列の残余部分への変数の代入</h4>

<p>配列を分割するときに残余パターンを使用して、配列の残りの部分を取り出して変数に代入できます。</p>

<pre class="brush: js notranslate">const [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 notranslate">const [a, ...b,] = [1, 2, 3];

// SyntaxError: rest 要素の末尾にカンマがあってはなりません
// 常に最後の要素として rest 演算子を使用してください。
</pre>

<h4 id="Unpacking_values_from_a_regular_expression_match" name="Unpacking_values_from_a_regular_expression_match">正規表現の一致からの値取得</h4>

<p>正規表現オブジェクトの <code><a href="/ja/docs/Web/JavaScript/Reference/Global_Objects/RegExp/exec"> exec()</a></code> メソッドは一致するものを見つけ、最初に一致した文字列全体の一部と、正規表現内の各括弧で囲まれたグループに一致した文字列の部分を含む配列を返します。分割代入によって、簡単にこの配列の一部分を取り出せます。また必要でない場合は、完全一致を無視できます。</p>

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

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

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

<h3 id="Object_destructuring" name="Object_destructuring">オブジェクトの分割代入</h3>

<h4 id="Basic_assignment" name="Basic_assignment">簡単な例</h4>

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

const {id, is_verified} = user;

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

<h4 id="Assignment_without_declaration" name="Assignment_without_declaration">宣言のない代入</h4>

<p>分割代入は代入文で宣言することなく行うことができます。</p>

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

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

<div class="note">
<p><strong>メモ</strong>: 代入文の周りの <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>

<p><code>( ... )</code> の式の前にセミコロンが必要です。そうしなければ、前の行の関数を実行に使用される可能性があります。</p>
</div>

<h4 id="Assigning_to_new_variable_names" name="Assigning_to_new_variable_names">異なる名前を持つ変数への代入</h4>

<p>オブジェクトから変数を取り出して、オブジェクトのプロパティとは異なる名前の変数に代入することができます。</p>

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

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

<p>ここで、例えば、<code>const {p: foo} = o</code> はオブジェクト <code>o</code> から <code>p</code> という名前のプロパティを取り、<code>foo</code> という名前のローカル変数へ代入します。</p>

<h4 id="Default_values_2" name="Default_values_2">既定値</h4>

<p>オブジェクトから取り出した値が <code>undefined</code> であるときの既定値を、変数に割り当てることができます。</p>

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

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

<h4 id="Assigning_to_new_variables_names_and_providing_default_values" name="Assigning_to_new_variables_names_and_providing_default_values">新しい変数名の割り当てとデフォルト値の提供</h4>

<p>両方ともプロパティにすることができます</p>

<ul>
 <li>オブジェクトから取り出して異なる名前の変数に代入します。</li>
 <li>取り出した値が <code>undefined</code> である場合に備えて、デフォルト値を割り当てます。</li>
</ul>

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

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

<h4 id="Unpacking_fields_from_objects_passed_as_function_parameter" name="Unpacking_fields_from_objects_passed_as_function_parameter">引数に指定されたオブジェクトの属性への参照</h4>

<pre class="brush:js notranslate">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>上記では <code>id</code>, <code>displayName</code>, <code>firstName</code> をオブジェクトから取得し、出力します。</p>

<h4 id="Setting_a_function_parameters_default_value" name="Setting_a_function_parameters_default_value">関数の引数に対する既定値の設定</h4>

<pre class="brush: js notranslate">function drawChart({size = 'big', coords = {x: 0, y: 0}, radius = 25} = {}) {
  console.log(size, coords, radius);
  // グラフの描画
}

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

<div class="note">
<p>上記の <strong><code>drawChart</code></strong> の関数シグネチャの中で、<code>{size = 'big', coords = {x: 0, y: 0}, radius = 25} = {}</code> として、分割代入の左辺に、右辺側で空のオブジェクトリテラルを代入しています。右辺の代入がない関数を記入することもできます。しかし、右辺の代入を取り除いた場合、関数は実行されたときに少なくともひとつの引数が提供されることを期待しますが、この形式では何も引数を指定せずに単純に <code><strong>drawChart()</strong></code> を呼び出すことができます。この設計は引数を指定せずに関数を呼び出せるようにしたい場合に役に立ちますし、もう一方の形式は、オブジェクトを確実に関数に渡したい場合に役に立ちます。</p>
</div>

<h4 id="Nested_object_and_array_destructuring" name="Nested_object_and_array_destructuring">入れ子になったオブジェクトと配列の分割代入</h4>

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

<h4 id="For_of_iteration_and_destructuring" name="For_of_iteration_and_destructuring">イテレーターでの分割代入の利用</h4>

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

<h4 id="Computed_object_property_names_and_destructuring" name="Computed_object_property_names_and_destructuring">計算されたオブジェクトのプロパティの名前と分割代入</h4>

<p><a href="/ja/docs/Web/JavaScript/Reference/Operators/Object_initializer#Computed_property_names">オブジェクトリテラル</a>のような計算されたプロパティの名前も分割代入で使用できます。</p>

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

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

<h4 id="Rest_in_Object_Destructuring" name="Rest_in_Object_Destructuring">オブジェクトの分割代入の残り</h4>

<p><a class="external external-icon" href="https://github.com/tc39/proposal-object-rest-spread">Rest/Spread Properties for ECMAScript</a> 提案 (ステージ 4) は、分割代入に <a href="/ja/docs/Web/JavaScript/Reference/Functions/rest_parameters">rest</a> 構文を追加しています。残余プロパティは、分割パターンによってすでに取り出されていない、残りの列挙可能なプロパティのキーを収集します。</p>

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

<h4 id="Invalid_JavaScript_identifier_as_a_property_name" name="Invalid_JavaScript_identifier_as_a_property_name">無効な JavaScript 識別子をプロパティ名として使用する</h4>

<p>JavaScript で有効な代替識別子を与えることにより、JavaScript で有効ではない{{glossary("Identifier", "識別子")}}であるプロパティ名を分割代入で使用できます。</p>

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

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

<h4 id="Combined_Array_and_Object_Destructuring" name="Combined_Array_and_Object_Destructuring">配列とオブジェクトの分割代入の組み合わせ</h4>

<p>配列とオブジェクトの分割代入は組み合わせることができます。配列 <code>props</code> の 3 番目の要素にあるオブジェクトの <code>name</code> プロパティが欲しい場合、次の操作ができます。</p>

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

const [,, { name }] = props;

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

<h4 id="The_prototype_chain_is_looked_up_when_the_object_is_deconstructed" name="The_prototype_chain_is_looked_up_when_the_object_is_deconstructed">オブジェクトが分割されるときにはプロトタイプチェーンが参照される</h4>

<p>オブジェクトが分割されるときで、自分自身のプロパティがアクセスされない場合は、プロトタイプチェーンを辿って参照が続けられます。</p>

<pre class="brush: js notranslate">let obj = {self: '123'};
obj.__proto__.prot = '456';
const {self, prot} = obj;
// self "123"
// prot "456"(プロトタイプチェーンへのアクセス)</pre>

<h2 id="Specifications" name="Specifications">仕様</h2>

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

<h2 id="Browser_compatibility" name="Browser_compatibility">ブラウザーの互換性</h2>

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

<h2 id="See_also" name="See_also">関連情報</h2>

<ul>
 <li><a href="/ja/docs/Web/JavaScript/Reference/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>