JavaScript入門 #文字列型 #数値型 #配列 #日付型 

## はじめに

本記事では、JavaScriptにおける[数値](#数値型)や[文字列](#文字列)や[日付](#日付と時刻)など様々なデータ型について関わりのあるメソッドを中心に周辺知識をまとめていきます。

今回の記事も[以前書いた記事][記事]と同様に以下のサイトのチュートリアルを進める中で学んだことをまとめていますのでJavaScriptを勉強している、してみたい方は是非参考にしてください！

https://ja.javascript.info/

## プリミティブのメソッド
JavaScriptにおけるプリミティブはオブジェクトとは別物ですがそれぞれメソッドも提供されています。最初にそのメソッドがどのように動作しているのかについて学びます。

> このプリミティブなデータとは、文字列、数値、長整数、論理値、`undefind`、シンボル、`null`のことを指します。
[参考][参考１]

最初に与えられた文字列をすべて大文字に変換するメソッドを用いて説明します。

```javascript:プリミティブのメソッド
let str = "Hello";

alert( str.toUpperCase() ); // HELLO
```

これから2行間で起きたことの説明に入ります。

１．文字列 str はプリミティブです。なので、プロパティへアクセスした瞬間に、文字列の値を知る特別なオブジェクトが作られ、それは toUpperCase() のような便利なメソッドを持っています

２．メソッドは実行され、新たな文字列を返します

３．特別なオブジェクトは破棄され、プリミティブの str だけが残ります。

> 書いたはいいものの、本質を掴めていない気がするので目を瞑ってもらえると嬉しいです。（大文字の子たちは変数として保持されないってこと？）

## 数値型
### 数値の区切り方

非常に大きな数字をコードとして記述する場合、見にくくなることがあります。しかし、

```javascript:数値型の表現１
let billion = 1000000000;
//上と下の数値はおなじ
let billion = 1_000_000_000;
```

ソースコード中の`_`は、“[糖衣構文][糖衣構文]” の役割をはたし、数値をより読みやすくします。

もしくは数字に`e`を付けたし、0の数を指定することでコードを短く書くことが出来ます。

```javascript:数値型の表現２
1e3 = 1 * 1000
1.23e6 = 1.23 * 1000000
let ms = 1e-6; // 1 から左にゼロを6つ
```

### n進数表現

特に16進数の数値は色、エンコード文字やその他多くのものを表現する文字としてJavaScriptで広く使われています。

それらを短く記述する方法が、2進数は`0b`,8進数は`0o`,16進数は`0x`を用います。

```javascript:n進数表現
let a = 0b11111111; // 255 の2進数表記
let b = 0o377; // 255 の8進数表記
let c = 0xff; // 255 の16進数表記
```

### 文字列に変換

`.toString(base)`を用いることで`base`進数に変換された`num`の値を文字列として返します。

```javascript:文字列変換
let num = 255;

alert( num.toString(16) );  // ff
alert( num.toString(2) );   // 11111111
```

### 数値の丸め込み

このセクションでは複数の丸め込み処理、そのコード例を示します。

１．切り捨て：`Math.floor`

２．切り上げ：`Math.ceil`

３．四捨五入により整数に変換：`Math.round`

４．小数点以下を切り捨て：`Math.trunc`

４．引数を小数点以下n桁に丸める：`toFixed(n)`

```javascript:文字列変換
let num = 255.12345;

alert( Math.floor(num) );  // 255
alert( Math.ceil(num) );   // 256
alert( Math.round(num) );   // 255
alert( Math.trunc(num) );   // 255
alert( num.toFixed(1) );   //255.1
```

### 特別な値のチェック

InfiniteとNaNの値は特別であり普通には比較が出来ないため比較するための特別なメソッドが存在します。

（復習）
Infinite：何よりも大きい数
NaN：エラー

```javascript:文字列変換
//isNaN(value) はその引数を数値に変換し、NaN であるかをテスト
alert( isNaN(NaN) ); // true
alert( isNaN("str") ); // true

//isFinite(value) は引数を数値に変換し、通常の数値であれば、true
alert( isFinite("15") ); // true
alert( isFinite("str") ); // false, 特別な値: NaN なので
alert( isFinite(Infinity) ); // false, 特別な値: Infinity なので
```

### 文字列から数値を取り出す

単位を持つような値に対して数値だけど取り出す処理を行いたいときには`parseInt`もしくは`parseFloat`メソッドが有効です。このメソッドは数値が読み込めなかった時にはNaNを返します。
早速コードを見てみましょう。

```javascript:parse〇〇メソッド
alert( parseInt('100px') ); // 100
alert( parseFloat('12.5em') ); // 12.5

alert( parseInt('12.3') ); // 12, 整数部のみ返却されます
alert( parseFloat('12.3.4') ); // 12.3, 2つ目の点で読むのをやめます

alert( parseInt('a123') ); // NaN, 最初の文字で処理が止まります
```

### その他数値用メソッド

- 乱数生成

`Math.random()`を用いると０から１の乱数を返します

- 最大・最小値を返却

`Math.max(a, b, c, ...n)`を用いると任意の数の引数から最大値を返します
`Math.min(a, b, c, ...n)`を用いると任意の数の引数から最小値を返します

- 累乗

`Math.pow(n, power)`を与えるとnを与えられた数だけ累乗します

```javascript:その他関数
alert( Math.random() ); // 0.1234567894322
alert( Math.random() ); // 0.5435252343232
alert( Math.random() ); // ... (any random numbers)

alert( Math.max(3, 5, -10, 0, 1) ); // 5
alert( Math.min(1, 2) ); // 1

alert( Math.pow(2, 10) ); // 2 in power 10 = 1024
```

## 文字列

JavaScriptでは、テキストデータは文字列として格納されます。1文字用の別の型はありません。

### 引用符の復習

引用符は３種類存在する。

```javascript:引用符
let single = 'single-quoted';
let double = "double-quoted";

let backticks = `backticks`;
```

この中ではバッククォートのみが異質な存在でした。
文字列の中に関数呼び出しを含む任意の式を埋め込むことができます。

- 例
```javascript:バッククォート例１
function sum(a, b) {
  return a + b;
}

alert(`1 + 2 = ${sum(1, 2)}.`); // 1 + 2 = 3.
```

また、まじ列の表示を複数行にまたがせることが出来ます。

```javascript:バッククォート例２
let guestList = `Guests:
 * John
 * Pete
 * Mary
`;

alert(guestList); // 複数行でのゲストのリスト
```

### 特殊文字

特殊文字を用いた文字列の表現方法を表形式で紹介します。

|文字|説明|
|:--|:--|
|\n|改行|
|\r|キャリッジリターン|
|\', \"|クォート|
|\\|バックススラッシュ|
|\t|タブ|
|\b|バックスペース|
|\xXX|16進数のユニコード XX であたえられるユニコード文字|
|/uXXX|\u00A9 のような16進コード XXXX を持つユニコード記号|

### 文字列の長さを確認する

`length`プロパティで文字列の長さを確認することが出来ます

```javascript:文字列の長さの確認
alert( `My\n`.length ); // 3
```
### 文字列の中の文字にアクセスする

文字の位置の文字を取得する場合、角括弧 `[ ]` を使うか、もしくは `str.charAt(pos)` メソッドを呼び出します。

```javascript:文字の検索
let str = `Hello`;

// 最初の文字
alert( str[0] ); // H
alert( str.charAt(0) ); // H

// 最後の文字
alert( str[str.length - 1] ); // o
```

### 部分文字列の検索

文字列の中で、部分文字列を探す方法はいくつかあります。

- `str.indexOf(substr, pos)`を用いる

これは str の中で substr を探し、与えられた pos の位置から開始して、見つかった位置、または見つからなかった場合は -1 を返します。

```javascript:部分文字列の検索
let str = 'Widget with id';

alert( str.indexOf('Widget') ); // 0, 'Widget' が先頭で見つかったので
alert( str.indexOf('widget') ); // -1, 見つかりませんでした。検索は文字大小を区別します

alert( str.indexOf("id") ); // 1, "id" は位置 1 で見つかりました(..idget の id)
```

- ` str.includes(substr, pos)`を用いる

str が substr 含むかどうかで true/false を返します。

```javascript:部分文字列の検索
alert( "Widget with id".includes("Widget") ); // true

alert( "Hello".includes("Bye") ); // false
```

ほかにもいくつか方法はありましたがここでは割愛します。


## 配列

JavaScriptには、順序付けされたコレクションを格納するために、Array と呼ばれる特別なデータ構造があります。

### 宣言

空の配列を作る2つの構文があります

```javascript:配列の宣言
let arr = new Array();
let arr = [];
```

### 要素の取得・追加・置き換え・表示

これは難しくもないのでソースコードのみ紹介します。
(基本的に操作したい要素番号を指定するだけです。)

```javascript:配列の操作
let fruits = ["Apple", "Orange", "Plum"];

//要素の表示
alert( fruits[0] ); // Apple
alert( fruits[1] ); // Orange
alert( fruits[2] ); // Plum

//要素の置き換え
fruits[2] = 'Pear'; // now ["Apple", "Orange", "Pear"]

//要素の追加
fruits[3] = 'Lemon'; // now ["Apple", "Orange", "Pear", "Lemon"]

//一覧の表示
alert( fruits ); // Apple,Orange,Pear, Lemon
```

### 要素の総数を取得

`length`を用いて配列の大きさを取得します。

```javascript:配列の大きさ
let fruits = ["Apple", "Orange", "Plum"];

alert( fruits.length ); // 3
```

### queueに関するメソッド

キュー(queue) は配列で最も一般的に使われるものの１つです。これは2つの操作をサポートする要素の順序付きコレクションを意味します。

- `push`

要素を末尾に追加します。

- `shift`

最初から要素を取得し、2番目の要素が1番目になるようにキューを進めます。


```javascript:
let fruits = ["Apple", "Orange"];

fruits.push("Pear");

alert( fruits ); // Apple, Orange, Pear


let fruits = ["Apple", "Orange", "Pear"];

alert( fruits.shift() ); // Apple を削除し alert する

alert( fruits ); // Orange, Pear
```

### stackに関するメソッド

- `push`

要素を末尾に追加します・

- `pop`

末尾から要素を取り出します。

```javascript:pop使用例
let fruits = ["Apple", "Orange", "Pear"];

alert( fruits.pop() ); // "Pear" を削除し alert する

alert( fruits ); // Apple, Orange
```

### 多次元配列

配列は配列も持つことができるため、多次元配列として表現することが出来ます。

```javascript:多次元配列の宣言
let matrix = [
  [1, 2, 3],
  [4, 5, 6],
  [7, 8, 9]
];

alert( matrix[1][1] ); // 中央の要素
```

## 配列に対するメソッド

### 配列から要素を削除する

配列から要素を削除するには`delete`を用いることが出来ます。

```javascript:配列の要素を削除する
let arr = ["I", "go", "home"];

delete arr[1]; // "go" を削除

alert( arr[1] ); // undefined

// now arr = ["I",  , "home"];
alert( arr.length ); // 3
```

### 配列の要素の削除・上書き・挿入

`arr.splice`を用いることで上記の3機能すべてを実現することが出来ます。

- 使い方
```javascript:arr.splice使い方
arr.splice(操作対象の開始インデックス, 削除する要素数, "挿入する要素", " ");
```

では次に具体的な操作方法を見ていきましょう

```javascript:配列の操作
let arr = ["I", "study", "JavaScript", "right", "now"];
// 最初の 3 要素を削除し、別のものに置換
arr.splice(0, 3, "Let's", "dance");
alert( arr ) // 今は ["Let's", "dance", "right", "now"]

let arr = ["I", "study", "JavaScript", "right", "now"];
// 最初の 2 要素を削除
let removed = arr.splice(0, 2);
alert( removed ); // "I", "study" <-- 削除された要素の配列

let arr = ["I", "study", "JavaScript"];
// インデックス 2 から
// 削除 0
// その後 "complex" と "language" を挿入
arr.splice(2, 0, "complex", "language");
alert( arr ); // "I", "study", "complex", "language", "JavaScript"
```

### 配列のコピー

配列をコピーするには`arr.slice()`メソッドを用います。
引数を指定することで部分的にコピーを行うことも可能です

- 使い方
```javascript:arr.slice()使い方
//部分的にコピー
arr.slice(start, end)
//すべてコピー
arr.slice()
```

では次に具体例を見ていきます。

```javascript:arr.splice使い方
let arr = ["t", "e", "s", "t"];

alert( arr.slice(1, 3) ); // e,s (1 から 3 をコピー)

alert( arr.slice(-2) ); // s,t (-2 から末尾まで)
```

> 引数の指定方法が実は腑に落ちていません。

### 配列の結合

`concat()`は配列を他の配列またはアイテムと結合します。

- 使い方
```javascript:concat()使い方
arr.concat(arg1, arg2...)
```

次に具体的な使い方を見ていきます。

```javascript:arr.concat()使い方
//部分的にコピー
let arr = [1, 2];

// arr と [3,4] をマージ
alert( arr.concat([3, 4])); // 1,2,3,4

// arr と [3,4] と [5,6] をマージ
alert( arr.concat([3, 4], [5, 6])); // 1,2,3,4,5,6

// arr と [3,4] をマージ後, 5 と 6 を追加
alert( arr.concat([3, 4], 5, 6)); // 1,2,3,4,5,6
```

### 配列の全要素に対する操作

`arr.forEach`メソッドは配列のの全要素に対して関数を実行することが出来ます。

- 使い方
```javascript:arr.forEach()使い方
arr.forEach(function(item, index, array) {
  // ... item に対して何か処理をする
});
```

具体的な使い方をアロー関数を用いて記述します。

```javascript:arr.forEach()使い方
["Bilbo", "Gandalf", "Nazgul"].forEach((item, index, array) => {
  alert(`${item} is at index ${index} in ${array}`);
});
```

### 配列の各要素に対して関数を呼び出し

`arr.map`メソッドは、配列の各要素に対して関数を呼び出し、結果の配列を返します。

次のソースコードでは各要素のもし列の長さを戻します。

```javascript:arr.map()使い方
let lengths = ["Bilbo", "Gandalf", "Nazgul"].map(item => item.length)
alert(lengths); // 5,7,6
```

### 配列の要素を逆にする

配列の中の要素を逆順に変換するには`reverse()`メソッドを用います。

```javascript:arr.reverse()使い方
let arr = [1, 2, 3, 4, 5];
arr.reverse();

alert( arr ); // 5,4,3,2,1
```

### 配列かどうかを確かめる

`Array.isArray(value)`はその値が配列であるのかどうかを論理値で返すメソッドです。

```javascript:Array.isArray(value)使い方
alert(Array.isArray({})); // false

alert(Array.isArray([])); // true
```

## 反復可能なオブジェクト

反復可能な(iterables) オブジェクトは配列の汎化です。これは`for..of`ループで任意のオブジェクトを使用できるようにするための概念です。

> 元気がなかったのでこの記事での理解は諦めます。参考ページを記載しておきますので許してください。

https://ja.javascript.info/iterable

## MapとSetについて

MapとSetは、JavaScriptにおけるデータ構造の一つです。
それぞれ順番に説明していきます。

### Map

Mapはオブジェクトと同じように、キー付されたデータ項目の集まりです。主な違いはMapは、任意の型のキーを許可することです。

使い方と主に使われるメソッドをソースコードで紹介します。

```javascript:Mapの使い方
//新しいMapを作成します
let map = new Map();

//キーで、値を格納します
map.set('1', 'str1');   // 文字列キー
map.set(1, 'num1');     // 数値キー
map.set(true, 'bool1'); // 真偽値キー

// Map は型を維持します。なので、これらは別ものです:
//指定されたキーの値を返却します
alert( map.get(1)   ); // 'num1'
alert( map.get('1') ); // 'str1'

alert( map.size ); // 3
```

また、Mapは、ループするための３つのメソッドがあります。

```javascript:Mapの使い方
let recipeMap = new Map([
  ['cucumber', 500],
  ['tomatoes', 350],
  ['onion',    50]
]);

// キー(野菜)の反復
//キーに対する iterable を返します
for (let vegetable of recipeMap.keys()) {
  alert(vegetable); // cucumber, tomateos, onion
}

// 値(量)の反復
//値に対する iterable を返します
for (let amount of recipeMap.values()) {
  alert(amount); // 500, 350, 50
}

// [key, value] エントリーの反復
//エントリ [key, value]　の iterable を返します。これは for..of でデフォルトで使われます
for (let entry of recipeMap) { // recipeMap.entries() と同じ
  alert(entry); // cucumber,500 (など)
}
```

### Set

Setは特別なタイプの集合でキーがない値の集合となっています。使用することが出来るメソッドはMapと似ており使いやすい印象です。

使い方と主に使われるメソッドをソースコードで紹介します。

```javascript:Setの使い方
let set = new Set();

let john = { name: "John" };
let pete = { name: "Pete" };
let mary = { name: "Mary" };

set.add(john);
set.add(pete);
set.add(mary);
set.add(john);
set.add(mary);

// set はユニークな値のみをキープします
alert( set.size ); // 3

for (let user of set) {
  alert(user.name); // John (そして Pete と Mary)
}
```

## WeakMapとWeakSetについて

先ほど紹介したMapとSetの親戚にWeakMapとWeakSetというものがあります。

WeakMapは、キーにはプリミティブな値ではなくオブジェクトでなければならず、
WeakSetはオブジェクトのみ追加が許されます。

次にソースコードを見てみます。

```javascript:WeakMap使用例
let weakMap = new WeakMap();

let obj = {};

weakMap.set(obj, "ok"); // 正常に動作します (オブジェクトのキー)

// キーに文字列は使えません
weakMap.set("test", "Whoops"); // エラー, "test" はオブジェクトではないため
```

```javascript:WeakSet使用例
let visitedSet = new WeakSet();

let john = { name: "John" };
let pete = { name: "Pete" };
let mary = { name: "Mary" };

visitedSet.add(john); 
visitedSet.add(pete); 
visitedSet.add(john); 

// visitedSet は 2 ユーザいます

// John が訪問したかどうかをチェック
alert(visitedSet.has(john)); // true

// Mary が訪問したかをチェック
alert(visitedSet.has(mary)); // false
```

## 日付と時刻

最後にDate型について説明していきます。日付型は、付や時刻を保存し、管理するためのメソッドが提供されており、作成/修正時刻を保存したり、時間を測定したり、単に現在の時刻を表示するために使うことができます。

新しいDateオブジェクトを作るには、次のいずれかの引数でnew Date()を用います。

### 呼び出し時の引数

- 引数無しだと現在の日付、時刻で作成されます

```javascript:引数なしで呼び出し
let now = new Date();
alert( now ); // 現在の日時を表示します
```

- millisecondsを指定すると1970年 1月1日 UTC+0 からの経過したミリ秒で作成されます

```javascript:millisecondsで呼び出し
// 0 は 01.01.1970 UTC+0 を意味します
let Jan01_1970 = new Date(0);
alert( Jan01_1970 );

// 今 24 時間を追加しました, 02.01.1970 UTC+0 になります
let Jan02_1970 = new Date(24 * 3600 * 1000);
alert( Jan02_1970 );
```

- datestring

1つの引数でそれが文字列の場合、自動でパースされます。

```javascript:datestringで呼び出し
let date = new Date("2017-01-26");
alert(date);  // Thu Jan 26 2017 11:00:00 GMT+1100 
```

- year, month, date, hours, minutes, seconds, ms

ローカルタイムゾーンで、与えられた要素で日付を作成します。最初の2つの引数は必須です。

```javascript:時間指定で呼び出し
let date = new Date(2011, 0, 1, 2, 3, 4, 567);
alert( date ); // 1.01.2011, 02:03:04.567
```

### データへアクセスするメソッド

オブジェクトの年、月、日などアクセスするメソッドを紹介していきたいと思います

- getFullYear()

年を取得します

- getMonth()

0から11で月を取得します

- getDate()

月の日を取得し、値は 1 から 31 です

- getHours()
- getMinutes()
- getSeconds()
- getMilliseconds()

対応する時刻の構成要素を取得します。

- getDay()

週の曜日を取得し、値は 0 (日曜) から 6 (土曜) です。


### 文字列から日付に変換

 Date.parse(str) メソッドは文字列から日付を読むことができます。
 
 文字列のフォーマットは`YYYY-MM-DDTHH:mm:ss.sssZ`でなければなりませんが、短く表現することは可能です。（例：`YYYY-MM-DD`, `YYYY-MM`）

では使用例を見てみます。

```javascript:文字列から日付の変換
let date = new Date( Date.parse('2012-01-26T13:51:50.417-07:00') );
alert(date);
```

## JSONメソッド

JSON (JavaScript Object Notation) は値とオブジェクトを表現する一般的な形式です。RFC 4627 で標準として記述されています。

### 提供されているメソッド

- `JSON.stringify`：オブジェクトをJSONに変換します

- `JSON.parse`：JSONをオブジェクトに変換します

現時点で筆者はあまり使い方がわかっていないため、最後にソースコードの紹介のみしていきます。（使う機会ができ次第更新予定）

```javascript:JSON.stringify使い方
let student = {
  name: 'John',
  age: 30,
  isAdmin: false,
  courses: ['html', 'css', 'js'],
  wife: null
};

let json = JSON.stringify(student);

alert(typeof json); // string です!

alert(json);
/* JSON-encoded object:
{
  "name": "John",
  "age": 30,
  "isAdmin": false,
  "courses": ["html", "css", "js"],
  "wife": null
}
*/
```

```javascript:JSON.parse使い方
let user = '{ "name": "John", "age": 35, "isAdmin": false, "friends": [0,1,2,3] }';

user = JSON.parse(user);

alert( user.friends[1] ); // 1
```

## さいごに

本記事ではJavaScriptに出てくる様々なデータ型について紹介し、それぞれの型に依存する便利なメソッドについて学びました。
経験が浅いため、どのメソッドが頻繁に使われているのか想像できない状態ですが、チートシート的な目的で使えるよう今後も記事を更新していけたらなと思います！

[記事]: https://qiita.com/masamasamasami/items/bfc51dd12b8c276b2186
[参考１]: https://developer.mozilla.org/ja/docs/Glossary/Primitive
[糖衣構文]: https://ja.wikipedia.org/wiki/%E7%B3%96%E8%A1%A3%E6%A7%8B%E6%96%87#:~:text=%E7%B3%96%E8%A1%A3%E6%A7%8B%E6%96%87%EF%BC%88%E3%81%A8%E3%81%86%E3%81%84%E3%81%93%E3%81%86%E3%81%B6%E3%82%93,%E3%81%A7%E3%81%8D%E3%82%8B%E3%82%82%E3%81%AE%E3%81%AE%E3%81%93%E3%81%A8%E3%81%A7%E3%81%82%E3%82%8B%E3%80%82