【JavaScript】データ型とリテラル

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

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

# この記事で理解できること
* JavaScriptの値のデータ型について
* データ型の分類(プリミティブ型、オブジェクト)
* 主要なデータ型のリテラル

# データ型とリテラル
* JavaScriptでは、変数に対する型は存在しないが、値には型(`文字列、数値、真偽値など`)が存在する。
* その値の型のことを`データ型`と呼び、大きく分けると二つ(`プリミティブ型`、`オブジェクト`)に分類される。

## プリミティブ型
* `文字列や真偽値、数値`など一度作成すると、値自体を変更できない`イミュータブル`な特性を持つ基本的な型。

|型|例・備考|
|--|--|
|真偽値(Boolean)|true、false|
|数値(Number)|123、1.234|
|巨大な整数(BigInt)|9007199254740992n ***1**|
|文字列(String)|"Hello World"|
|undefined|値が未定義であること意味する|
|null|値が存在しないことを意味する|
|シンボル(Symbol)|一意で不変な値 ***2**|

***1** `ES2020`から追加された
***2** `ES2015`から追加された

```js
// type演算子でデータ型を調べた例
console.log(typeof true);                    // => boolean
console.log(typeof 114);                     // => number
console.log(typeof 9007199254740992n);       // => bigint
console.log(typeof "JavaScript");            // => string
console.log(typeof Symbol("シンボル"));        // => symbol
console.log(typeof undefined);               // => undefined
console.log(typeof null);                    // => object
console.log(typeof ["配列"]);                 // => object
console.log(typeof { "key": "value" });      // => object
console.log(typeof function() {});           // => function
```
> **nullについて**
> nullをtypeof演算子で評価すると`object`と判定される。
> 歴史的経緯を持つ`バグ`で、既にこの挙動に依存しているコードへの影響などを考慮され、修正が見送られている。

> **undefinedについて**
> `undefined`という値を持ったグローバル変数。
> 同じ変数名でローカル変数を宣言できるが非推奨。

## オブジェクト
* プリミティブ型以外のもの(`オブジェクト`、`配列`、`関数`、`正規表現`、`Data`など)
* `複数のプリミティブ型の値`、または`オブジェクト`の集まり。
* 一度作成した後も、オブジェクトが持つ値を変更できる`ミュータブル`な特性を持つ。
* オブジェクトは、値そのものではなく`値への参照`を経由して操作されるため、`参照型のデータ`とも言う。

```js
// キーname、ageとそれぞれ値を持つオブジェクト
const member1 = {
  name: 'Taro',
  age: 21,
};

// ドット(.)やブラケット([])でオブジェクトが持つプロパティの値を参照できる
console.log(member1.name);    // => Taro
console.log(member1["name"]); // => Taro
```

# リテラル
* プログラム上で`数値、文字列`などのデータ型を直接`表現・記述できる構文`のこと。
* よく利用されるプリミティブ型やオブジェクトの`リテラル`が用意されている。

# プリミティブ型のリテラル
* 真偽値(Boolean)
* 数値(Number）
* 巨大な整数(BigInt)
* 文字列(String）
* null

## 真偽値（Boolean）
* `true`と`false`のリテラルが存在する。
* 当たり前のように使っていた`true、false`は「`true、falseを返すリテラル(構文)`」だった。

```js
console.log(true);  // => true
console.log(false); // => false
```

## 数値（Number）
数値のリテラルには、以下の2種類が存在する。
(変数の先頭に`数値`を使用できないのは、この数値リテラルとの衝突を避けるため)

* 整数リテラル(`例：24`)
* 浮動小数点数リテラル(`例：3.14159`)

### 整数リテラル
* 2進数：0b(0B)から始まる`0,1`の組み合わせ
* 8進数：0o(0o)から始まる`0 ~ 7`の組み合わせ
* 10進数：`0 ~ 9`の組み合わせ
* 16進数：0x(0x)から始まる`0 ~ 9`,`a ~ z`または`A ~ Z`の組み合わせ

```js
/* 各進数で「13」を表現 */
// 2進数
console.log(0b01101);

// 8進数
console.log(0o015);

// 10進数
console.log(13);

// 16進数
console.log(0x000D);
```

### 浮動小数点数リテラル
* ドット（`.`）を含んだ数値：0.123
* `e(E)`を含んだ数値：2e2(指数表現)
※e(E)の後は`指数`(10のn乗の「n」部分)を指定する

```js
// ドットを含めた値
console.log(0.123);      // => 0.123

// 先頭の「0」を省略することは可能(オブジェクトの値参照時のドット記法を考慮すると省略しない方が良い)
console.log(.123);       // => 0.123

// 以下は「2 * 10の2乗」と同じ意味
console.log(2e2);        // => 200

// e以降は整数でなければならない
console.log(2e2.22);     // => ×
```

## 文字列（String）
* 文字列リテラルは、`同じ記号で囲んだ内容を文字列として扱う`という共通のルールがある。
* 使用できる記号として、ダブルコーテーション`(")`、シングルコーテーション`(')`、テンプレートリテラル(`` ` ``)の3種類が存在する。
* 改行を含めたい場合は、`エスケープシーケンス(\n)`を使用する。

```js
// 「"」ダブルコーテーション
console.log("文字列"); // => 文字列

// 「'」シングルコーテーション
console.log('文字列'); // => 文字列

// 文字中に同じ記号を含めたい場合は、「\」バックスラッシュでエスケープできる
console.log("「\"」をエスケープ"); // => 「"」をエスケープ

// エスケープシーケンスで改行
console.log("今日の天気は\n晴れです"); 
// => 今日の天気は
//    晴れです

// 「`」テンプレートリテラル
console.log(`文字列`); // => 文字列

// テンプレートリテラルは、エスケープシーケンス(\n)無しで複数行の文字列を書くことが可能
console.log(
`今日の天気は
晴れです`
);
// => 今日の天気は
//    晴れです
```

## テンプレートリテラル[ES2015]
* `ES2015`から導入された。
* エスケープシーケンス(`\n`)を用いずに複数行の文字列を書くことができる。
* プレースホルダー(ドル記号と波括弧`${}`)を利用し、変数の値を埋め込むことや計算式の記述などが可能。<br>(タグ付きテンプレートなども存在する『[テンプレートリテラル (テンプレート文字列)](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Template_literals)』)

```js
// 埋め込む変数を定義
const weather = "晴れ";

// エスケープシーケンス(\n)を用いずに複数行の文字列を書くことができる
console.log(
`今日の天気は
${weather}です`
);
// => 今日の天気は
//    晴れです

// 文字中に含めたい場合は、「\」バックスラッシュでエスケープできる
console.log(`「\`\`」をエスケープ`); // => 「``」をエスケープ
```

## nullリテラル
* `null`値を返すリテラル。
* `null`値を代入することで「`値がない`」ということを表現できる。

```js
const notValue = null;
console.log(notValue); // => null
```

# オブジェクトのリテラル
以下3つのリテラルが存在する。

* オブジェクトリテラル
* 配列リテラル
* 正規表現リテラル

## オブジェクトリテラル
* `{ }`のこと。
* オブジェクトリテラル`{ }`を用いて新しいオブジェクトを作成できる。
* オブジェクト作成時に`キー(key):値(value)`を同時に定義することも可能。

```js
// 新しく空のオブジェクトを作成
const obj1 = {};
console.log(obj1); // => {}

// キー(key):値(value)を同時に定義し、作成
const obj2 = {
  name: "Taro",
  age: 24
};
console.log(obj2); // => {name: 'Taro', age: 24}

// それぞれドット記法、ブラケット記法でキーを指定し値を参照できる
// この時指定するキーを「オブジェクトのプロパティ(名)」と呼ぶ
console.log(obj2.name);   // => Taro
console.log(obj2["age"]); // => 24
```

## 配列リテラル
* `[`と`]`内に値をカンマ(`,`)区切りArrayオブジェクトを作成できる。

```js
// 名簿のような配列を作成
const nameList = ["Taro", "Hanako", "Tom"];
console.log(nameList[0]) // => Taro
```

## 正規表現リテラル
* `/(スラッシュ`)で文字列を囲うことで、正規表現の`パターン文字列`であることを表現できる。

```js
/* 先頭が英小文字という正規表現パターン */
// 正規表現リテラルで生成したパターンはRegExp(正規表現オブジェクトとなる)
const pattern = /^[a-z]/;

// 正規表現パターンで検証する文字列
const value1 = 'abcde';
const value2 = 'Abcde';

/* RegExp(正規表現)オブジェクトが持つtestメソッドで判定 */
// パターンに一致していればtrue
console.log(pattern.test(value1)); // => true
// パターンに一致していなければfalse
console.log(pattern.test(value2)); // => false
```