東京の会社辞めて地方で生きるわ。

勢いで会社を辞めて縁のない地方で生きることはできるのか

Javascript オブジェクト指向 メモ

JavaScriptは、インスタンス化/インスタンスという概念はあるが、いわゆるクラスがなく、「プロトタイプ(ひな形)」という概念だけが存在する点である。
プロトタイプとは、「あるオブジェクトのもととなるオブジェクト」のことで、Javascriptではこれを利用して新たなオブジェクトを生成していくことになる。

もっともシンプルなクラスを定義する

var Member = function(){};
「変数Memberに対して、空の関数リテラルを代入しているだけ」だが、これがJavascriptのクラスなのである。Javascriptでは関数(Functionオブジェクト)にクラスとしての役割を与えている。

実際、このMemberクラスは以下のようにnew演算子インスタンス化できる。

var mem = new Member();

コンストラクタで初期化する

このように、new演算子によってオブジェクトを生成することを想定した関数オブジェクトのことをコンストラクタという。
コンストラクタとは「インスタンス(オブジェクト)を生成する際に、オブジェクトを初期化する処理を記述するための特殊なメソッド(関数)」のことをいう。


hogeクラスをつくるとき

// コンストラクタ
var Member = function(firstName, lastName){
  this.firstName = firstName;  // 左辺のfirstNameはthisつまりMemberオブジェクトのプロパティを定義。右辺は仮引数(一つ上の行のfirstName)のfirstName。
  this.lastName = lastName;
  this.getName = function(){ // メソッドを定義。ここではgetNameプロパティに匿名関数を引き渡しているので「getNameメソッド」を宣言したことになる。
    return this.lastName + ' ' + this.firstName;
  }
};

// メソッド
Member.prototype = {
  f1: function() {
    return true;
  },
  f2: function() {
    return false;
  }
};

var mem = new Member(' 太郎', '山田'); // Memberオブジェクトをインスタンス化して、getNameメソッドを呼び出している。
document.writeln(mem.getName());

ここで注目すべきなのは、thisキーワード。thisキーワードは、コンストラクタによって生成されるインスタンス(つまり、自分自身)を表すものです。thisキーワードに対して変数を指定することで、インスタンスのプロパティを設定できる。

プロパティの定義・メソッドの定義

>||

this.プロパティ名 = 値;

|

また、プロパティには文字列や整数、日付などだけではなく、関数オブジェクト(関数リテラル)を指定できる。javascriptにおいては、厳密にはメソッドという概念はなく、

値が関数オブジェクトであるプロパティがメソッドとみなされる。

ここではgetNameプロパティに匿名関数を引き渡しているので「getNameメソッド」を宣言したことになる。


プロトタイプでメソッドを宣言する(prototypeプロパティ)

上記のコンストラクタによるメソッドの追加にはデメリットがあり、

メソッドの数に比例して「無駄な」メモリを消費する

コンストラクタはインスタンス(new Member)を生成するたびに、プロパティやメソッドをコピーするから重くなっちゃう。

そこでjavascriptではオブジェクトにメンバを追加するためにprototypeというプロパティを用意している。
このprototypeプロパティに格納されたメンバは、インスタンス化された先のオブジェクトに引き継がれる。
以下、例。

var Member = function(firstName, lastName){
  this.firstName = firstName;
  this.lastName = lastName;
};

var mem = new Member('太郎', '山田');

Member.prototype.getName = function(){
  return this.lastName + ' ' + this.firstName;
};

document.writeln(mem.getName());

上のコードはgetNameメソッドを、new演算子によってインスタンスを生成した後に追加しているという点に注目。この場合でも問題なくメソッドを認識できることが確認できる。