【JavaScript】文字列① 〜文字列の作成・結合・アクセス・内部変換〜

# 概要
JavaScriptを学習、理解を深めるため「[JavaScript Primer 迷わないための入門書](https://jsprimer.net/)」を読み、
理解した内容等を記載していく。

「[【JavaScript】JavaScript入門一覧](https://qiita.com/andota05/items/22fae452225b785fd405)」に他の記事をまとめています。

# この記事で理解できること
* 文字列の作成方法
* JavaScriptにおける文字コード

# 文字列の作成
* 文字列リテラル(`"`、`'`、`` ` ``)のいずれかを利用し、文字列を作成する。
* `対となる文字列リテラル`で、文字を囲う必要がある。

```js
// ダブルクォート
const str1 = "文字列1";

// シングルクォート
const str2 = '文字列2';

//　バッククォート(ES2015〜 テンプレートリテラルという)
const str3 = `文字列3`;

const str4 =`複数行記載することができます
複数行記載することができます
`;
console.log(str4);
// => 複数行記載することができます(ちゃんと改行されて)
// => 複数行記載することができます
```

# エスケープシーケンス
* 文字列リテラルにそのまま入力できない特殊文字は、`\`と組み合わせた`エスケープシーケンス`として特殊文字を表現する。
* [MDN](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/String#escape_notation)などを参考にするのが吉
* `\`がついた文字は自動的にエスケープシーケンスと認識されるが`未定義であった場合は無視`される。

```js
// 文字列リテラルとして使用している " を文字列に含める
const str5 = "今日の天気は\"晴れ\"です";
console.log(str5); // => 今日の天気は"晴れ"です

// \n は改行を表す特殊文字
const str6 = "明日の天気は\n曇り\nです";
console.log(str6);
// => 明日の天気は
// => 曇り
// => です

// 本当は \ を含めたかったとする　
const str7 = "\A\B\C\D" // 「\」から始まっているため、エスケープシーケンスとして扱われている
console.log(str7); // => ABCD ※\が無視されている(\Aなどは特殊文字として存在しないため)

// 「\」自体をエスケープする　
const str8 = "\\A\\B\\C\\D"
console.log(str8); // => \A\B\C\D
```

# 文字列を結合する
* `文字列結合演算子(+)`で文字列を結合する。
* `変数との結合`も可能。
* 変数との結合の際、テンプレートリテラル(`` ` ``)を使用すると`+`を書く手間も省け、宣言的に記載できる。

```js
// 文字列同士を結合
const str9 = "a" + "b";
console.log(str9); // => ab

// 変数と結合
const str10 = str9 + "c";
console.log(str10); // => abc

// テンプレートリテラル (変数を ${変数名} と指定する)
const str11 = `${str10}の次はdです`;
console.log(str11); // => abcの次はdです
```

# 文字へのアクセス
* 配列のインデックスと同じように文字列の`特定の文字`に対し、インデックスを指定しアクセスできる。
* 存在しないインデックスを指定した場合には、`undefined`が返される。

```js
const str12 = "ABCDEFG";

// 文字列にインデックスを指定しアクセス
console.log(str12[2]); // => C
```

# 改めて文字列とは
ここまで、文字列の作成~アクセスについて記載したが、この記事上で目にしている文字列「Qiita」や「JavaScript」「文字列」などをそのままコンピュータで扱うことは難しく、コンピュータが扱えるように`符号化`という仕組みを用いて`0、1`のビット列に変換されている裏事情がある。

## 押さえておきたい用語
|用語|概要|備考|
|--|--|--|
|符号化(エンコード)|文字を`0、1のビット列`に変換すること||
|符号化文字集合|符号化された`0、１のビット列`が何の文字なのかを表す対応表||
|文字コード|符号化文字集合の対応表の名前、種類|UnicodeやASCIIなど|
|符号化(エンコード)方式|符号化する際の方法、方式|UTF-8や、UTF-16など|

混同してしまう点として`UTF-8`や`UTF-16`は文字コードではなく、`符号化(エンコード)方式`であることに留意したい。

※Web上の記事によっては「`Unicodeの文字コードであるUTF-8`」のような表現があったりする...

# JavaScript内部における文字コード
* JavaScript内部では`Unicode`の`UTF-16`という符号化方式を採用している。
* `Unicode`では、1文字を表すのに使う最小限のビットの組み合わせを`Code Unit（符号単位）`と呼ぶ。
* UTF-16では各Code Unitのサイズが`16ビット（2バイト）`。

>**UTF-16とは**
>それぞれの文字を16ビット(16桁の0、1の組み合わせ)に変換する方式
>「UTF-8」は予想がつく通り、それぞれの文字を8ビット(8桁の0、1の組み合わせ)に変換する方式

## CodeUnitに関連するメソッド
### charCodeAtメソッド
* 文字列の指定したインデックスの文字のCode Unitを整数として返す。

```js
console.log("ABC".charCodeAt(0)); // => 65("A"のCodeUnit)
```

### String.fromCharCodeメソッド
* Code Unitを文字へと変換する。

```js
const str13 = "ABC";

console.log(str13.charCodeAt(0)); // => 65("A"のCodeUnit)

// NumberオブジェクトのtoStringメソッドで16進数表記に変換
console.log(str13.charCodeAt(0).toString(16)); // => 41("A"の16進数表記)
const a2hex = str13.charCodeAt(0).toString(16);

// String.fromCharCodeメソッドで文字へ変換「0x」は16進数を表すリテラル
console.log(String.fromCharCode(`0x${a2hex}`));
// => A

/* 2進数でも表記でも同じことができる **/
// NumberオブジェクトのtoStringメソッドで2進数表記に変換
console.log(str13.charCodeAt(0).toString(2)); // => 1000001("A"の2進数表記)
const a2bin = str13.charCodeAt(0).toString(2);

// String.fromCharCodeメソッドで文字へ変換「0b」は2進数を表すリテラル
console.log(String.fromCharCode(`0b${a2bin}`));
// => A
```

上記のようにJavaScriptで文字列を扱う際には、「内部的にこのような変換が行われているんだな」という理解ができたと思う。