JavaScript はプリミティブ(文字列、数値など)をオブジェクトのように扱うことができます。また、それらはメソッドも提供しています。この後すぐに学んでいきますが、最初に、どのように動作するのか確認しましょう。なぜなら、プリミティブはオブジェクトではないからです(このチャプターでそれをさらに明確にしていきます)。
プリミティブとオブジェクトの主な違いを見ていきましょう。
プリミティブ
- プリミティブ型の値です。
- プリミティブ型は 7 つあります:
string,number,bigint,boolean,symbol,null,undefined
オブジェクト
- プロパティとして複数の値を保持することができます。
{}で作ることができます。例えば:{name: "John", age: 30}。JavaScriptでは他の種類のオブジェクトもあります。関数もオブジェクトです。
オブジェクトの最も良いところの1つは、そのプロパティの1つとして関数を保持することができることです:
let john = {
name: "John",
sayHi: function() {
alert("Hi buddy!");
}
};
john.sayHi(); // Hi buddy!
上の例では、sayHi メソッドをもつ john オブジェクトを作りました。
日付、エラー、HTML要素などで動作するような、多くの組み込みのオブジェクトが既に存在し、それらは異なるプロパティとメソッドを持っています。
しかし、これらの機能にはコストがかかります!
オブジェクトはプリミティブよりも “重い” です。内部の仕組みをサポートするために追加のリソースを必要とします。しかし、プロパティやメソッドはプログラミングをする上で非常に有用であり、JavaScriptエンジンはそれらの負担を減らすために最適化を試みます。
オブジェクトとしてのプリミティブ
JavaScriptの作成者が直面するパラドックスは次の通りです。:
- 文字列や数字のようなプリミティブに対してやりたいことがたくさんあります。 それらをメソッドとして実現することは素晴らしいことでしょう。
- プリミティブはできるだけ高速、かつ軽量でなければなりません。
解決策は少々野暮ですが次の通りです:
- プリミティブは依然としてプリミティブです。要望どおり、単一の値です。
- 言語は、文字列、数値、真偽値そしてシンボルのメソッドやプロパティにアクセスすることができます。
- 必要に応じて、追加の機能を提供する特別な “オブジェクトラッパー” が作られ、その後、破棄されます。
“オブジェクトラッパー” はプリミティブ型毎に異なり、String, Number, Boolean, Symbol と呼ばれます。従って、それらは異なるメソッドのセットを提供します。
例えば、大文字化された文字列を返す str.toUpperCase() というメソッドがあります。
次のように動作します:
let str = "Hello";
alert( str.toUpperCase() ); // HELLO
シンプルですよね? str.toUpperCase() で実際に何が起こっているのでしょう:
- 文字列
strはプリミティブです。なので、プロパティへアクセスした瞬間に、文字列の値を知る特別なオブジェクトが作られ、それはtoUpperCase()のような便利なメソッドを持っています。 - メソッドは実行され、新たな文字列を返します(
alertで表示されたものです) - 特別なオブジェクトは破棄され、プリミティブの
strだけが残ります。
従って、プリミティブは依然として軽量なままですが、メソッドを提供できます。
JavaScriptエンジンはこの処理を高度に最適化しています。余分なオブジェクトの作成を完全にスキップするかもしれません。しかし、それは依然として仕様に準拠し、あたかもオブジェクトを作成したかのように動作しなければなりません。
数値は自身のメソッドを持っています。例えば、指定された精度に数値を丸める toFixed(n) です: