JavaScriptのオブジェクトについて解説してみた【開眼JavaScriptまとめ】
目次
今回からシリーズ物として、僕が開眼JavaScriptという技術書を呼んでみて勉強した内容をまとめていきます。 まず最初はJavaScriptのオブジェクトについてを解説します。
開眼JavaScriptとは?
最初に本記事の参考文献である開眼JavaScriptという技術書について軽く説明したいと思います。 開眼JavaScriptの正式なタイトルは”開眼JavaScript 言語仕様から学ぶJavaScriptの本質”といいます。
そのタイトル通りではありますが、JavaScriptの言語特性で知っておくべきポイントを纏めた書籍です。挫折しがちな点である、this、プロトタイプチェーン(継承)、スコープチェーンなどが、サンプルを使って説明されています。
JavaScriptのバージョンはES3を参考に書かれているため、古い仕様ではありますが、JavaScriptの本質的な理解を助けてくれる1冊です。
JavaScriptのオブジェクトの本質
冒頭に述べたようにこの記事ではJavaScriptのオブジェクトについて解説します。開眼JavaScriptでは、オブジェクトを下のように定義しています。
オブジェクトとは、名前と値を持つプロパティを格納するコンテナにすぎない。また、プログラミング言語を扱う以上、名前と値だけでは、JSONのようなデータベースにすぎないため、メソッドを与える必要があります。 そして、本書ではJavaScriptのメソッドについても定義されています。以下の文章です。
JavaScriptでの「メソッド」は、オブジェクト上で動作するよう意図した関数オブジェクトを持ったプロパティこのように定義されています。
次に、JavaScriptに元から定義されている9つのオブジェクトについて説明します。
ビルトインオブジェクトについて
JavaScriptは9つのビルトインオブジェクトコンストラクターを持っています。これらのビルトインオブジェクトは、値を表すためのみに使用されるのではなく、言語のさまざまな機能を整えるために使用されています。
avaScriptは9つのビルトインオブジェクトは以下のとおりです。
- Number()
- String()
- Boolean()
- Object()
- Array()
- Function()
- Date()
- RegExp()
- Error()
プリミティブ型(基本型)の値について
さきほど、JavaScriptは”ほぼ”全体がビルトインオブジェクトで構成されていると述べました。”ほぼ”というのは、JavaScriptにはオブジェクトではない既約が存在するからです。それが、3、foo、true、false、null、undefinedなどのプリミティブ型(基本型)になります。 これらの値はこれ以上単純化されないため、プリミティブ値であるとみなされます。
簡単に言うとJavaScriptにおいて、1番低いレイヤーの単位です。
次にオブジェクトの生成方法について説明していきたいのですが、その前にコンストラクターという概念について説明して置かなければいけません。
コンストラクターとは何か
コンストラクターとは関数です。そのため、コンストラクター関数と呼ぶこともあります。 そして、コンストラクター関数がどんな役割を果たしているのかというと、あらかじめ決められたオブジェクトを生成するテンプレートの役割をしてくれています。例えるならば、クッキーの抜き型のようなものとでもいいましょうか。オブジェクトの生成
次にオブジェクトの生成方法について学びましょう。オブジェクトを生成する方法は2通り存在します。new演算子と、コンストラクター関数を使用する方法とリテラルを使用する方法です。
それぞれについて、詳しく見ていきましょう。
new演算子とコンストラクター関数を使う
JavaScriptでは、new演算子とコンストラクター関数をつかうことでオブジェクトを生成できます。配列を生成するビルトインオブジェクトコンストラクターであるArray()
を例に取ってみましょう。
const array = new Array('foo', 'bar'); console.log(array); // 結果:['foo', 'bar']
new Array()
の形でArray()
のインスタンスである配列オブジェクトを生成できます。
これは、以前述べたJavaScriptのビルトインオブジェクトコンストラクター9つすべてにおいて、new演算子を使ってオブジェクトのインスタンス化ができます。
リテラルを使う
オブジェクトを生成する方法としてもう1つの方法が、リテラルを使用する方法です。リテラルとは、new演算子を使用した場合と同じ意味を表すショートカットです。ほとんどの場合では、リテラルを使用してオブジェクトを作成します。
次の例では、new演算子を使ったビルトインコンストラクター、そして同等の操作を行うリテラルを使ったインスタンスオブジェクトを生成します。
このように、JavaScriptではnew演算子とコンストラクター関数を使わず、リテラルを使うことで簡単にインスタンスオブジェクトを生成できます。
しかし、プリミティブ型の文字列や数値、真偽値は少し複雑になります。これらに関してはオブジェクトではなくプリミティブ型の性質を持つからです。
これから詳しく説明します。
プリミティブ型の文字列や数値、真偽値はオブジェクトのように扱うとオブジェクトのようにふるまう
よく”JavaScriptはすべてがオブジェクトである”という解釈が存在するが、これは誤解である。実際には、”JavaScriptでは全てがオブジェクトのようなふるまいをする”という解釈が正解である。
具体的には、コンストラクターによって生成されたオブジェクトを使うようにプリミティブ型をつかうとJavaScriptはその命令を実行するために、プリミティブ値を一時的にオブジェクトに変換します(プリミティブ値を保管する「ラッパーオブジェクト」が生成される)。そのオブジェクト(ラッパーオブジェクト)は命令が実行された後に破棄され、値はプリミティブ型に戻ります。
次に、プリミティブ値をオブジェクトとして扱うとどうなるかをコードで確認します。
const premitive = "foo";
const length = premitive.length;
console.log(length): // 結果:3
length
プロパティを取得するためにfoo
という文字列がオブジェクトに変換され、プロパティが呼ばれると、プリミティブ値に戻ります。
上記のように、プリミティブ型はオブジェクトのように扱うとオブジェクトのようにふるまうのです。
ちなみに、null
とundefined
はコンストラクターをもっていないため、オブジェクトに変換されません。
JavaScriptオブジェクトとデータ型のオブジェクトを区別する
最後にJavaScriptで「オブジェクト」と表現する際の注意点を示したいと思います。JavaScriptのおいて、オブジェクトとは2つの意味があります。それは、
- JavaScriptでのオブジェクトを一般的に表す「JavaScriptオブジェクト」
- データ型である
Object()
Array()
オブジェクトは「配列」と呼ばれる「JavaScriptオブジェクト」であります。また、Object()
オブジェクトは「オブジェクト」と呼ばれる「JavaScriptオブジェクト」であります。
Object()
オブジェクトは特別な値の種類を表すデータ型です。これを広義の「JavaScriptオブジェクト」と混同しないようにしましょう。
まとめ
- オブジェクトとは、名前と値を持つプロパティを格納するコンテナにすぎない
- JavaScriptは、Number()、String()、Boolean()、Object()、Array()、Function()、Date()、RegExp()、Error()という9つのビルトインオブジェクトコンストラクターを持つ
- プリミティブ型(基本型)とはJavaScriptにおいて1番低いレイヤーの単位である
- コンストラクター関数とは、あらかじめ決められたオブジェクトを生成するテンプレート
- オブジェクトは、new演算子と、コンストラクター関数を使用するか、リテラルを使用することで生成される
- プリミティブ型はオブジェクトのように扱うとオブジェクトのようにふるまう
Object()
オブジェクトとJavaScriptオブジェクトを区別する