jsの型まとめ

# 型
プリミティブ型とオブジェクト型に別れる。

||値|属性|
|:---:|:---:|:---:|
|プリミティブ型|immutable|プロパティやメソッドを持たない|
|オブジェクト型|mutable|プロパティやメソッドを持つ|

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/406130/b8992fdc-5e71-3095-0eb2-ab6e3ce842c0.png)

参考
https://qiita.com/yuta0801/items/f8690a6e129c594de5fb

## 文字列型と文字列オブジェクト(Stringクラス)

```js
var str = "abc" //文字列型
var strObj = new String("abc") //文字列オブジェクト
```

### 文字列型と文字列オブジェクトの暗黙裡の変換
本来、`str`にはメソッドがないのでlengthメソッドで長さを取得できないが、実際には`str.length`として取得できる。これは、lengthメソッドへのアクセスの際に文字列オブジェクトへ暗黙の型変換が行われ、実行後元の文字列型に戻るため、見た目上(typeof演算子上)で`string`だが、一時的にオブジェクトとしての振る舞いができる。

`str.length`や`"abc".length`が可能なのは一時的にキャストされているため。

なお、逆に、＋演算子で文字列型と文字列オブジェクトをくっつける場合には、文字列型への暗黙の変換が行われる。

```js
type(strObj)
// 'object'
type(strObj + "def") // 文字列型に変換される。
// 'string'
```

なお、==演算子と===演算子は、比較時に暗黙的に型を変換するかの違い。
前者は変換を行うが、後者は行わないたね、より厳密な型チェックとなる。

```js
str == str
// true
str === str
// true
str == strObj   // 型変換されるため
// true
str === strObj
// false
strObj == new String("abc")  // new演算子で生成されるオブジェクトは中身が同じでも参照先が異なるため不一致
// false
```

### 型変換関数 String()
String()は明示的な型キャストの関数。実はStringクラスのメソッド。
pythonでいうところの`str()`、C++でいうところの`static_cast<String>`

## Stringクラスのプロパティ
よく使うようtoString()やmatch()、trim()などはいづれもprototupeプロパティの中にある。lengthはこの中ではなく、prototypeと並列に位置しており、常に値は1である。

なお、プロパティに持つ関数は全て非破壊的な関数であり、文字列を書き換えることはせず新しい値を返すものになる。以下のようにプロパティを用いた場合、新しい文字列が生成され、もとのオブジェクトは不変(immutable)である。

```js
strObj.toUpperCase()
// 'ABC'
typeof(obj.toUpperCase())
// 'string'
```

## Stringオブジェクトのプロパティ
文字列値とlengthを持つ。このlengthは文字列長さを返す。

## 数値型と数値オブジェクト(Numberクラス)
64bitの浮動小数点型(これ以外にはない)。

```js
var num = 1 //数値型
var numObj = new Number(1) //数値オブジェクト
```

### 数値型と数値オブジェクトの暗黙裡の変換
文字列とStringクラスの関係と一緒。一時的なキャストにより`num.toString()`や`(1).toString`が可能。括弧は小数点との区別のために必要。


### 型変換関数 Number()
Number()は明示的な型キャストの関数。実はNumberクラスのメソッド。

## Numberクラスのプロパティ
Stringクラスより多くのプロパティがある。

|プロパティ名|意味|
|:---:|:---:|
|length|常に1|
|MAX_VALUE|正の最大値|
|MIN_VALUE|正の最小値|
|NaN|Not a Number|
|NEGATIVE_INFINITY|-∞|
|POSITIVE_INFINITY|+∞|
|prototype|プロトタイプ|

## 特別値(NaN、±INFINITY)
NaNを与えた全ての演算の結果はNaNとなる。これは比較演算子も例外ではないため、NaNであることの確認には定義済み関数であるisNaN()を用いる必要がある。

同じくisFinite()関数ではinfinityおよびNaN以外であるかの判定が可能である。

また、特別値との剰余算の結果は以下。（正常値としては1を取り上げる）

|x|y|x/y|x%y|
|:---:|:---:|:---:|:---:|
|1|∞|0|1|
|1|0|∞|NaN|
|0|0|NaN|NaN|
|∞|1|∞|NaN|
|∞|∞|NaN|NaN|

## 真偽値型と真偽値オブジェクト(Booleanクラス)
ほんとか嘘か。trueかfalse。

```js
var flag = true //数値型
var flag = new Boolean(true) //数値オブジェクト
```

### 真偽値型と真偽値オブジェクトの暗黙裡の変換
文字列とStringクラスの関係と一緒。一時的なキャストにより`num.toString()`や`(1).toString`が可能。

### 型変換関数 Boolean()
Boolean()は明示的な型キャストの関数。実はBooleanクラスのメソッド。
通常、読み取り時に暗黙裡に型変換されるので明示的に変換する必要はない。

## Booleanクラスのプロパティ
prototypeとlength(常に1)のみ。なお、Booleanオブジェクトにはlengthプロパティがない。

# null型
何も参照していない状態を意味する。null型はnull値のみとることができ、nullはリテラル値である。
ただし、typeof演算子にかけると返値はobjectであるため===演算で確認する必要がある。

```js
typeof(null)
// 'object'
null === null
true
```

またnullにはNullクラスが存在しないため、プロパティやメソッドを有さない。

# undefined型
同じくundefined値のみ持つ。typeof演算の結果は文字列undefinedが返る。nullと違い、undefinedはリテラル値ではなく、定義されたグローバル変数である。
null同様にUndefinedクラスは存在しない。

# BigInt型、Symbol型
// これから書きます。

# object型
上述の基本型以外は全てobjectである。
ただし、関数は、objectの一種であるもののtypeof演算の結果は'function'を返す。

# 型変換
## 文字列 → 数値
### 明示的なキャスト

|||
|:---:|:---|
|Number()|問答無用にnumber型に変える。数値以外が入ってるとNaNになる。|
|parseInt()|数値以外は無視して整数へ。第2引数に基数(n進数)を指定できる|
|parseFloat()|数値以外は無視して少数へ。|

```js
parseInt("ff", 16)
// 255
```

### 暗黙的なキャスト

```js
//単項演算子(+)
+'1'
// 1
//算術演算子(-)
'2' - '1'
// 1
```

ただし、算術演算子(+)は、文字列の結合を可能なため、上記の演算を行うと21が返る。

## 数値 → 文字列
### 明示的なキャスト

```js
String(1)
(1).toString()
```

### 暗黙的なキャスト

```js
//算術演算子(+)
'2' + '1'
// 21
```

## その他の型変換
### null型 → 数値型
null型nullを数値型へ変換すると0になる。NaNではない！

### object型

|変換先|実行されるメソッド|
|:---:|:---:|
|文字列型|toString|
|数値型|valueOf(もしくはtoString)なければ'NaN'|
|真偽値型|__常にtrue__|

よくデバッグで`console.log("value:" + obj)`とすると`[object Object]`が入ってて中に潜れなくなるのはこのため。