JavaScript入門 その2：配列、オブジェクトリテラル

JavaScript入門の書籍を読んで書いてあったこと＋自分で調べたことのメモ書きその2。関数、配列、オブジェクトリテラル。

# 配列

### 配列のプロパティ、メソッド

`arr` を配列とする。

#### length
`arr.length`
配列の要素数のプロパティ。

#### push
`arr.push(要素1[, 要素2, …, 要素N])`
配列の末尾に要素を追加する。
破壊的。

#### pop
`arr.pop()`
配列の末尾の要素を取り出す。
破壊的。

#### unshift
`arr.unshift(要素1[, 要素2, …, 要素N])`
配列の先頭に要素を追加する。
破壊的。

#### concat
`arr.concat([要素1, 要素2, …, 要素N])`
配列を結合する。
引数がない場合は元の配列 **シャローコピー** を返す。
非破壊的。

#### splice
`arr.splice(削除開始位置[, 削除要素数, 追加要素1, 追加要素2, …, 追加要素N])`
配列の要素の追加・削除を行う。
削除開始位置が -N（負の数）の場合、後ろからN番目の要素から削除する。
削除要素数が0の場合は削除開始位置の次の位置に追加要素を挿入する。
破壊的。

#### indexOf
`arr.indexOf(探す値[, 検索開始位置])`
引数の値と最初に一致する要素のインデックスを返す。
非破壊的。

#### lastIndexOf
`arr.lastIndexOf(探す値[, 検索開始位置])`
引数の値と最後に一致する要素のインデックスを返す。
非破壊的。

#### fill
`arr.fill(値, 変更開始位置, 変更終了位置)`
変更開始位置から変更終了位置までの要素を値に変更する。`arr.fill(値, 2, 4)` なら `arra[2]` と `arr[3]` の2要素を変更する。
破壊的。

#### slice
`arr.slice(開始位置[, 終了位置])`
開始位置から終了位置までの要素を持つ新しい配列を返す。終了位置がない場合は開始位置以降すべて。`arr.slice(2, 4)` なら `arr[2]` と `arr[3]` を要素とする新しい配列を返す。
非破壊的。

```js
let zodiac = ["おとめ", "てんびん", "さそり"];
zodiac.push("いて", "やぎ");
zodiac.unshift("かに", "しし");
console.log(zodiac);
let arr = zodiac.slice(5);
arr.push("うお");
console.log(arr);
console.log(zodiac);
```

【実行結果】
```console
['かに', 'しし', 'おとめ', 'てんびん', 'さそり', 'いて', 'やぎ']
['いて', 'やぎ', 'うお']
['かに', 'しし', 'おとめ', 'てんびん', 'さそり', 'いて', 'やぎ']
```

### 配列のシャローコピー、ディープコピー

シャローコピーは要素がオブジェクトではない場合、各要素はオリジナルの配列と同じものを参照している。よってオリジナルとシャローコピーはオブジェクト型の要素を変更すると互いに影響を受ける。逆に言えばオブジェクト型ではない要素であれば変更しても互いに影響はない。

ディープコピーはすべての要素がオリジナルの配列とは異なるものを参照しているので変更は互いに影響しない。

シャローコピーは先にあげた `concat()` を使う他にスプレッド構文を使う方法がある。

```js
let arr1 = arr.concat();
let arr2 = [...arr];
```


# 文字列

### 文字列中の文字の参照

配列のようにインデックスを指定して文字列中の1文字を参照できる。ただし配列と異なり変更することはできない。

```js
let word = "たんご";
console.log(word[1]);
```

【実行結果】
```console
ん
```

### テンプレートリテラル
バッククォートで囲って記述した文字列。改行がそのまま反映されるので改行を含む長い文字列を書く場合は便利である。
また文字列中で変数を `${…}` をの形式で展開することできる。

```js
let name = "ガンダム";
let modeNumber = "RX-78";
let height = "18.0m";
let weight = "60.0t";
let profile = `名称：${name}
型式番号：${modeNumber}
全高：${height}
重量：${weight}`
console.log(profile);
```

【実行結果】
```console
名称：ガンダム
型式番号：RX-78
全高：18.0m
重量：60.0t
```

### String.raw
`String.raw` を用いた記法を使うとバックスラッシュをエスケープしなくても記述できる。
`String.raw` の後にテンプレートリテラルで記述する。括弧は不要。

```js
console.log(String.raw`C:\Users\hoge\Documents\memo.txt`);
```

【実行結果】
```console
C:\Users\hoge\Documents\memo.txt
```


### 文字列のメソッド

`str` を文字列とする。

#### includes
`str.includes(検索文字列)`
指定した検索文字列が含まれているかを返す。

#### replace
`str.replace(置換対象, 置換文字列)`
最初に現れた置換対象を置換文字列に置換する。
置換対象は正規表現も使える。

#### replaceAll
`str.replaceAll(置換対象, 置換文字列)`
置換対象すべてを置換文字列に置換する。
置換対象は正規表現も使える。

#### trim
`str.trim()`
先頭と末尾のホワイトスペースを削除する。

#### split
`str.split(セパレータ)`
セパレータ文字列で分割した配列を返す。
セパレータは文字列、正規表現を指定できる。


# オブジェクトリテラル

プロパティ名（キー）は変数として有効な文字列の場合と数字の場合はダブルクォートで囲む必要はない。

```js
let obj = {
  abc: "xyz",
  1: 100,
};
```

### プロパティの参照の仕方
角カッコでプロパティ名を囲むブラケット記法とドットの後にプロパティ名を書くドット記法がある。
プロパティ名が変数に入っている場合はブラケット記法しか使えない。

```js
let key = "abc";
console.log(obj.abc, obj[key]);
```

【実行結果】
```console
xyz xyz
```

### in演算子
`in`演算子はオブジェクトに指定したプロパティが存在するかを返す。

```js
console.log("abc" in obj);
```

【実行結果】
```console
true
```


# 参考情報

### 書籍
[解きながら学ぶJavaScriptつみあげトレーニングブック | マイナビブックス](https://book.mynavi.jp/ec/products/detail/id=126984) 4章

### WEBページ
[［JavaScript］Arrayメソッド破壊・非破壊チートシート - Qiita](https://qiita.com/Shokorep/items/929e2e66908eaa915286)
[Javascript配列のコピー方法(Deep/Shallow/代入)備忘録 #JavaScript - Qiita](https://qiita.com/tomson/items/2138a9aa2ae244686197)