JavaScriptにクラスはありません - オブジェクトリテラルとコンストラクタパターン編 -
そもそも
今月頭にこの記事を見て、げっと思ったので……。
Class構文が実装された - JS.next
JavaScriptにクラスは存在しません!!!にもかかわらず、class構文なるものを用意するのは余計に初学者を混乱させるだけだと思います。個人的な復習も兼ねて、オライリー『JavaScriptパターン』に載っているオブジェクト作成とコード再利用のパターンから、自分なりに内容を噛み砕いてまとめてみました。
JavaScriptパターン ―優れたアプリケーションのための作法
- 作者: Stoyan Stefanov,豊福剛
- 出版社/メーカー: オライリージャパン
- 発売日: 2011/02/16
- メディア: 大型本
- 購入: 22人 クリック: 907回
- この商品を含むブログ (77件) を見る
方法1: オブジェクトリテラルを使う
クラスはオブジェクトを作るひな形でありオブジェクトではありません。JavaScriptではクラスがないため、オブジェクトはすべて既存のオブジェクトのコピーになります。
var Person = { myName: "noname", sayName: function(){ console.log("I am " + this.myName); } }; Person.sayName(); // "I am noname" var John = Person; var Bob = Person; John.sayName(); // "I am noname" Bob.sayName(); // "I am noname"
Personはクラスではなくオブジェクトです。John、BobはPersonと同じプロパティ(myName, sayName)を持っていますが、これはPersonオブジェクトのコピーだからです。しかしこのやり方には問題があります。
John.myName = "John"; John.sayName(); // "I am John" Bob.sayName(); //"I am John" Person.sayName(); //"I am John"
Johnのプロパティを書き換えるとPersonやBobのオブジェクトも書き換わってしまいます。これは期待した動作ではないので工夫が必要になります。
方法2: コンストラクタパターンを使う
次はPersonにオブジェクトリテラルではなく関数(コンストラクタ)を代入して使ってみます。
var Person = function Person(myName){ this.sayName = function(){ console.log("I am " + myName); }; this.sayHo = function(){ console.log("Ho!"); } }; var John = new Person("John"); var Bob = new Person("Bob"); John.sayName(); // "I am John" John.sayHo(); // "Ho!" Bob.sayName(); // "I am Bob" Bob.sayHo(); // "Ho!" John.sayHo = function(){ console.log("HOOOOOOOOOOOOO!!!!"); }; John.sayHo(); // "HOOOOOOOOOOOOO!!!!" Bob.sayHo(); // "Ho!" var LadyGaga = new Person("Gaga"); LadyGaga.sing = function(){ console.log("lalalala lalalala"); }; LadyGaga.sayName(); // "I am Gaga" LadyGaga.sayHo(); // "Ho! LadyGaga.sing(); // "lalalala lalalala"
newキーワードでJohnとBobのオブジェクトを生成することができました。両者ともPersonで定義されているプロパティにアクセスでき、一方のプロパティを書き換えたとしても他方に影響をあたえることはありません。
では最後に出てきたLadyGagaのように、Personのプロパティを継承しつつ、新たなプロパティ(sing)を追加したオブジェクトを生成したい場合はどうすればよいでしょうか。この例ではLadyGagaオブジェクトを作った後にsingプロパティを追加していますが、これはなかなか見通しが悪いです。
といったときにでてくるのがプロトタイプなのですが、長くなりそうなので続きは次回。