はじめに
オブジェクト指向という言葉はプログラミングを始めると必ず聞く言葉です。
オブジェクトとは、「データの集合とそのデータの手続き(処理内容)ひとまとめにしたもの」の事です。
そして、それらのオブジェクトを基本単位としてプログラム作成を行う事を、「オブジェクト指向」と言います。
JavaやC++、他にはRuby、Python、JavaScriptはオブジェクト指向をベースとしたプログラミングを行う事ができますが、オブジェクトを定義する方法に違いがあります。
それはクラス(class)を使用する方法と、プロトタイプ(prototype)を使用する方法です
上記のJava、C++はクラスを使用し、Ruby、Python、JavaScriptはプロとタイプを使用します。
※JavaScriptについては、JavaScriptの標準であるECMAScript2015にて仕様が大きく変わりクラスを使用する事が可能となりました。後述します。
この記事ではJavaScriptでのオブジェクト指向プログラミングの基礎という事で、オブジェクトの作成、コンストラクタの使い方について説明します。
JavaScriptのオブジェクトとは
オブジェクトの基本
プログラムを作成していて、データを保管するために、「変数」や「配列」を使用する事があるはずです。
変数はある特定の値を一時的に保管する場合に使用しますが、配列の場合は、関係のある複数の値を保管するために使用します。
オブジェクトにデータを保管する場合は、複数のデータを名前と一緒に定義する事ができます。
この「名前:値」のセットをプロパティと呼びます。
これがオブジェクトの特徴です。
例えば、学校に通う生徒のデータを格納する場合は、以下のように定義する事ができます。
(実装例)
|
const school = { grade: '1', //学年 class: '1', //クラス number: '15', // 出席番号 name: '田中太郎', //名前 } |
上記の例では、schoolというオブジェクトの中に、「学年」、「クラス」、「出席番号」、「名前」のプロパティがありそれぞれにデータが格納されています。
もう一つ、オブジェクトの中には、「名前:関数」のセットを保管する事もできます。
このセットの事をメソッドと呼びます。
(実装例)
|
const greeting = { hello: function() { console.log( 'こんにちは' ); } } |
上記の例では、greetingというオブジェクトの中にhelloというメソッドを定義しています。
JavaScriptでは、他のオブジェクト指向言語と同様に「コンストラクタ」と言うものがあります。
以降で、コンストラクタの説明をします
コンストラクタとは
オブジェクト指向のプログラミングを勉強した際に「コンストラクタ」という言葉を聞いたことがあるかもしれません。
クラスからインスタンスを生成する際に「new」を使用しますが、この「new」を実行したタイミングでコンストラクタの機能が呼び出されます。
一般的には、インスタンス生成時にかならず実行されるものなので、メンバ変数の初期化に使用されることが多いです。
JavaScriptのコンストラクタの使い方
JavaScriptでは、オブジェクトやその機能を初期化するためにコンストラクタ―関数という関数を使用します。
コンストラクタとして関数を定義する場合には慣例として名前の1文字目を大文字にします。
メソッドの定義方法①(コンストラクタ内でメソッド定義)
プロパティとメソッドを定義する場合の構文は以下のようになります。
(構文:プロパティとメソッド定義①)
|
function コンストラクタ名( 引数1 [, 引数2] [, …] ) { // プロパティを定義 this.プロパティ名 = 値; // メソッドを定義 this.プロパティ名 = function(){ ... }; }; |
(実装例)
|
function Greeting(name) { this.name = name; //プロパティを定義 this.myName = function() { //メソッドを定義 alert('こんにちは!! 私の名前は ' + this.name + 'です.'); }; } |
上記の例の場合、Greetingのコンストラクタが呼び出された場合に必ずmyNameメソッドがメモリ空間上にコピー(オブジェクトが展開される)ため、システム領域内のメモリ空間を無駄に消費してしまうというデメリットがあります。
そこで、prototypeを使用したメソッド定義をする事で、上記のデメリットを解消する事ができます。
メソッドの定義方法②(prototypeを使用したメソッド定義)
prototypeとはプロパティの事で、このプロパティを使用してメソッドも一緒に定義した場合、メソッドが毎回メモリ空間上にコピーされずに、「参照」により使用されます。
「コピー」の場合は、メモリ上にオブジェクトそのもの生成されますが、「参照」の場合は、オブジェクト自体が生成されることはなく、データを参照しているだけです。
複雑なメソッドや、多数のメソッドの場合、インスタンス生成の都度同じ内容のメソッドが生成されるため、メモリ空間を無駄に使用して、システム稼働に影響を与えてしまう可能性があります。
prototypeによりメモリ空間の節約を図るのが得策でしょう。
(構文:プロパティとメソッド定義②)
|
function コンストラクタ名( 引数1 [, 引数2] [, …] ) { this.プロパティ名 = 値; // プロパティを定義 }; // prototypeを使用してメソッドを定義 オブジェクト名.prototype.メソッド名 = function(){ ... }; |
(実装例)
|
function Greeting(name) { this.name = name; //プロパティを定義 }; Greeting.prototype.myName = function() { //メソッドを定義 alert('こんにちは!! 私の名前は ' + this.name + 'です.'); }; |
このようにprototypeを使用して実装する事で、メソッドが都度コピーされることはなくなります。
システムの安定稼働のために有効に使用したい実装方法となります。
クラスの定義とコンストラクタ(ECMAScript2015以降)
従来、JavaScriptではクラスが存在しませんでしたが、2015年に発表されたJavaScriptの国際的な標準を示すECMAScript2015(ECMAScript6)(「エクマスクリプト」と読みます)において、JavaScriptの仕様が大きく変わりました。
その大きな変化の一つに、これまでになかったクラスを定義する事ができるようになっています。
当初は対応しているブラウザも少なく、実装可能なシーンが限定的でしたが、現時点では主要な最新ブラウザについてはほぼ対応が完了しており、実装可能な状況となっています。
まとめ
今回JavaScriptのオブジェクトとコンストラクタについての概要と、メソッドの実装例をご説明しました。また、prototypeを使用した実装例もご説明しています。
メソッド次第ではシステムのメモリ領域を圧迫してしまう可能性があるため、prototypeを使用した実装が現実的です。
ぜひご自身で実装する際には、稼働後の状況も考慮するように注意を払うようにしてみてください。