JavaScriptにおける配列リテラルとコンストラクターの違いについて[小ネタ]

## 0.はじめに

こんにちは。
エンジニアしている @gkzz です。

JavaScriptのお勉強をしているのですが、[Google JavaScript Style Guide](https://google.github.io/styleguide/jsguide.html#features-arrays-ctor)を読んでいて気になった箇所がありました。

>5.2.2 Do not use the variadic Array constructor
>The constructor is error-prone if arguments are added or removed. >Use a literal instead.
>
>Disallowed:
>
>const a1 = new Array(x1, x2, x3);
>const a2 = new Array(x1, x2);
>const a3 = new Array(x1);
>const a4 = new Array();

そういえば、[]とnew Array()。
違いってあるのだろうか。
気になったので、早速調べて、まとめました。

今回、調べるにあたり、[playcode.io](https://playcode.io/)というオンラインコンソールを使いました。

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">知らんかった。<br><br>&gt;5.2.2 Do not use the variadic Array constructor<br>The constructor is error-prone if arguments are added or removed. Use a literal instead.<br><br>さっそくオンラインコンソールにて挙動調査。<a href="https://t.co/EPbli1EfGz">https://t.co/EPbli1EfGz</a> <a href="https://t.co/PAykEEOLhX">pic.twitter.com/PAykEEOLhX</a></p>&mdash; gakuji tamaki (@gkzvoice) <a href="https://twitter.com/gkzvoice/status/1261532610703945728?ref_src=twsrc%5Etfw">May 16, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>



## 1.非推奨のArrayコンストラクターを使った場合

```.js
let data2 = new Array(10);

console.log("data2: " + data2);
console.log("data2[0]: " + data2[0]);
console.log("data2.length: " + data2.length);

console.log("#######################");

data2[0] = 10;

console.log("data2: " + data2);
console.log("data2[0]: " + data2[0]);
console.log("data2.length: " + data2.length);
```


```
data2: ,,,,,,,,,
data2[0]: undefined
data2.length: 10
#######################
data2: 10,,,,,,,,,
data2[0]: 10
data2.length: 10
```

### ポイント
- `new Array(10)とは、lengthが10である配列を定義`
  - ひとつひとつの要素はカラであり、undefinedとなる
  - 要素を定義する場合、data2[0] = 10;とする必要がある
- 一方、`new Array("10")と文字列の場合、lengthが1である配列を定義` 
  - data[0]の値は文字列の10
- 「new Array()の使いどころ」にてコンストラクターの使いどころについて後述


## 2.推奨されている配列の書き方

左記の[Google JavaScript Style Guide](https://google.github.io/styleguide/jsguide.html#features-arrays-ctor)には、推奨された書き方も紹介されています。

>Instead, write
>const a1 = [x1, x2, x3];
>const a2 = [x1, x2];
>const a3 = [x1];
>const a4 = [];

先ほどと同様、出力結果も確認してみましょう。

```.js

let data1 = [10];

console.log("data1: " + data1);
console.log("data1[0]: " + data1[0]);
console.log("data1.length: " + data1.length);

console.log("#######################");

data1[0] = 1;

console.log("data1: " + data1);
console.log("data1[0]: " + data1[0]);
console.log("data1.length: " + data1.length);
```

```
data1: 10
data1[0]: 10
data1.length: 1
#######################
data1: 1
data1[0]: 1
data1.length: 1
```

### ポイント
- `let data = [10]とは、lengthが1であり、data[0]の値は10ことを定義`
  - data1[0]がundefinedではなく、格納した値が入っている


## 3.new Array()の使いどころ
new Array()の使いどころが気になったので、調べたところ、下記の記事が参考になったので、引用させていただきます。

>`一つずつ要素を入れて配列長をじわじわ伸ばしていくより、最初にまとめて確保しておいた方が軽い`という理屈だ。
>古いJavaScriptエンジンでは有効なテクニックだったのだが、エンジンの進歩により、逆転現象が起きている。V8で測定すると[]を使った方が2倍ほど速かった。
>
>というわけで、 `今の時代、タイプ数の多い new Array をあえて使う必要はない。`

出所：[new Array()と[]の違い](https://qiita.com/Hiraku/items/d74690088dfa368875c9)

[]とnew Array()。
配列を扱いたい場合、[]でOKということですよね。


## p.s.JavaScriptにおいてメモリが解放されるタイミングはいつなのか

メモリはいつ開放されるのか？という点も気になったので、こちらについても私の理解と参考になった箇所を書き留めておきます。

- メモリが開放されるタイミングは分からない
- `ある領域にオブジェクトが管理されていてだれからも参照されなくなったら回収される`と理解すればよさそう


>JavaScript(ECMAScript)の仕様では、いつメモリが解放されるのかは定められていません。GC(ガベージコレクション)がいつ動作するのか、また、そのGCで回収されるのかはJavaScriptエンジンによって異なり、一概には言えません。
(中略)
>ある領域にオブジェクトが管理されていてだれからも参照されなくなったら回収されるというのが肝心な点なのでそこだけぶれなければOKじゃないでしょうか。

出所：[javascriptの変数のメモリへの割当について](https://teratail.com/questions/72635)


んー。。
<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">分かったようなわからないような汗。<br><br>&gt;ある領域にオブジェクトが管理されていてだれからも参照されなくなったら回収されるというのが肝心な点なのでそこだけぶれなければOKじゃないでしょうか。<br><br>「javascriptの変数のメモリへの割当について」 <a href="https://t.co/mDaMOvK55p">https://t.co/mDaMOvK55p</a> <a href="https://twitter.com/hashtag/teratail?src=hash&amp;ref_src=twsrc%5Etfw">#teratail</a></p>&mdash; gakuji tamaki (@gkzvoice) <a href="https://twitter.com/gkzvoice/status/1261617658132217856?ref_src=twsrc%5Etfw">May 16, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

## P.P.S. Twitterもやってるのでフォローしていただけると泣いて喜びます:)

[@gkzvoice](https://twitter.com/gkzvoice)