プリミティブ型について
プリミティブ型とは何か?
プリミティブとは、原始的なという意味を表す英単語で、
ここでは、最も基本的なデータ型を指します。
もっと、専門的に言うと、
オブジェクトではなく、メソッドやプロパティを持たないデータ型のこと指すよう。
オブジェクトは、プリミティブ以外のもので、
代表的なのは、
const obj = {name: 'obj', age: 19} //jsの場合
const obj: { name: string, age: number} = {name: 'obj',age: 19} //tsの場合
のような感じだ。
本記事はプリミティブ型の解説を主軸とするので、
オブジェクトには深入りしないが、
オブジェクトは、nameやageのようなプロパティを持っている。
プロパティとは、上記のname(キー),'obj'(value)を合わせたものを指す。
つまり、プリミティブ型は、
平たく言うと、今まで使ってきた'hello'といった文字列や、
100といった数字型のように、その値しかないものと言えそう。
変数とかに定義された際に、
呼び出し方によって、値が変わる、つまり複数の値が予め備わっていないものと
考えれば問題ないだろう。
さて、そんなプリミティブ型は、全部で7種類存在する。
(本記事では、bitint型とシンボル型は、基礎からはやや外れるので
これらは別の記事で解説する)
number型
これはその名の通り、
数値を表す型である。
const num = 5
ただ、TypeScript独特の仕様として、
number型には整数と小数の区別がありません。
下記では、整数しか定義していないが、
計算結果は、小数になっている。
const num1: number = 5
const num2: number = 8
const num3: number = 3
const ans: number = (num1 + num2) * num3 /2
console.log(ans) //19.5と表示される
string型
こちらも、基本的な型で、
'hello'のような文字列の型である。
文字列の作り方として、
""と''で囲うやり方があり、
基本的には大差ない。
const hello: string = 'hello'
const hello1: string = "hello"
テンプレートリテラル
さらに、テンプレートリテラルという、
記法も存在する。
これは、文字列の中に変数を入れることができるというメリットがある。
記法としては、``とバッククオートで囲む。
const str1: string = 'hello world'
const str2: string = 'HELLO WORLD'
console.log(`${str1}, ${str2}`)// "hello world, HELLO WORLD" と表示される
console.log('${str1}, str2') // "${str1}, str2"と表示される
//テンプレートリテラルでないと、変数名そのものが文字列になる。
boolean型
boolean型とは、真偽値のことで、
trueまたはfalseの2種類だけの値からなる型である。
const bool1: boolean = false
const bool2: boolean = true
boolean型は、条件分岐と交えて使用することがほとんで、
trueのときと、falseのときで実行したい処理を分けたいif文などでよく使われる。
真偽値変換の結果
実はわざわざtrueとかfalseと書かなくても、
どんな値も真偽値に変換されれば、この二種類のどちらかとなる。
そのため、条件分岐では、
値がそのまま入れられることも多い。
if (0) console.log(0) //0はfalseなので実行されない。
if (1) console.log(1) //1はtrueなので実行される。
if ('hello') //'hello'はtrueなので実行される
if (num1 < num2) //num1の方がnum2未満なら実行され、そうでないと実行されない条件分岐
ちなみに、falseに判定されるものは、
false, ""(空文字列), 0, NaN, null, undefinedで、
それ以外はすべてtrueと判定される。
null型とundefined型
null型は、その名のとおり、
nullという値だけをもつ型です。
undefined型も同様で、
undefinedという値だけを持つ型です。
const num: null = null
const num2: undefined = undefined
これらは、データがないということを表すものです。
他のRubyなどの言語では、
こういったデータがないという型は、
nilなどのように一種類のことが多いのですが、
TypeScriptでは、このように二種類存在します。
基本的に、こういった型は、自分で定義するものではなく、
メソッドや関数などの返り値がデータがない、
null型とかだった場合に、別の処理を記述するといったようにして、
null型を減らすよう努める類のものです。
なので、この2つが出てきたら、
データがないと捉えれば問題ないです。
ラッパーオブジェクトとは
プリミティブ型は、オブジェクトと違って、
メソッドを持ちません。
しかし、あたかもメソッドを持つかのように振る舞います。
例えば、"hello"というのは、
文字列でプリミティブ型なので、
本来メソッドを持ちません。
けれども、下記のようにincludesメソッドを実行できます。
"hello".includes("h")
これは、"hello"という文字列のラッパ−オブジェクト,Stringに変換され、
そのラッパーオブジェクト経由でメソッドが呼び出せれているので、
あたかもオブジェクトのように振る舞っているということです。
すなわち、
new String("hello").includes("h")
と同義です。
typeofを使うとわかるが、
"hello"は文字列なのに対し、
new String("hello")は
オブジェクトになる。
const str1 = new String("hello")
const str2 = "hello"
console.log(typeof str1); // object
console.log(typeof str2); // string
メソッドはオブジェクトでないと、呼び出せないのに、
プリミティブ型からも呼び出せるように見えるのは、こういう仕掛けがあるからです。
ちなみに、数値型は、Number、真偽値は、Booleanといった
ラッパーオブジェクトがある。
詳細は、下記に書かれてある。
なぜ、長々とこんなことを説明したのかというと、
冒頭でプリミティブ型は、プロパティやメソッドを持たないと言った意味が、
上記のラッパーオブジェクトに関わっているからだ。
プリミティブ型とは何かという定義に対し、
ドキュメントもラッパーオブジェクトに言及して説明している。
これで下記のドキュメントで言っている意味がわかるようになるはずです。
プリミティブ型は、nullとundefined以外、
ラッパーオブジェクトを持っている。
それはすなわち、ラッパーオブジェクトがないと、
メソッドなどを実行できないからだ。
nullとundefinedには当てはまらないが、この2つはやや特殊なので、
プリミティブ型とは何かという問いに対し、
対応するラッパーオブジェクトを持ち、
メソッドを実行する際、それに変換されるものと考えた方が、
わかりやすいかもしれない。