jsのprototypeの話
jsはクラスベースじゃなくてprototypeベースのオブジェクト指向だよ。
的なことは前から知ってて、いつかちゃんと勉強しようと思いながらずるずると伸びてた。
バイトでちゃんと勉強しろって指摘されたので、この機会に勉強してその結果をまとめてみる。
prototypeって?
jsでオブジェクトを生成した時に、生成されたオブジェクトの親になってるオブジェクト。
基本的に全てのオブジェクトはprototypeを継承する。
継承するprototypeは自分で選んだり、自分で作ることもできる。
利点
- 継承関係を作りやすい
- メモリを節約できる
どういう時に使うか
jsでクラスを作る時ってこんな感じでできる。
var Human = function (name){ this.name = name; this.say = function() { return ("My name is " + this.name); } } var takanamito = new Human('takanamito'); console.log(takanamito.say()); // Myname is takanamito
でもこれだとHumanオブジェクトを生成するたびに
sayっていう関数オブジェクトも生成されてしまって、メモリを無駄遣いする感じになる。
それを防ぐためにprototypeを使う。
var Human = function (name){ this.name = name; } Human.prototype = { say: function() { return ("My name is " + this.name); } } var takanamito = new Human('takanamito'); var hogehoge = new Human('hogehoge'); console.log(takanamito.say()); // Myname is takanamito console.log(hogehoge.say()); // Myname is hogehoge
こうすることで
takanamitoもhogehogeも1つのprototypeオブジェクトである
{ say: function() { return ("My name is " + this.name); } }
を参照するのでメモリを節約できる。※{}はオブジェクト生成のコンストラクタ
こうやってprototypeを自由に設定することで
すごく簡単にオブジェクトの継承ができる。
むずかったとこ
javascriptのオブジェクト指向とかプロトタイプとか - (゚∀゚)o彡 sasata299's blog
この記事のBoxの部分の話
なんでblueBoxだけcolorがyellowになるのか理解できなかったけど
Box.prototype = { color: "blue" };
の部分が理解できてなかったのが問題だった。
この部分でBoxのプロトタイプオブジェクトを代入し直してて
redBoxとblueBoxが参照しているプロトタイプオブジェクトが別になっている。※{color: "red"}, {color: "blue"}はそれぞれ別のオブジェクトだから。
だからこの後に
Box.prototype.color = "yellow";
をすると
blueBoxのプロトタイプオブジェクトだけが変更されて
redBoxの方に影響は出ない。
prototypeのデメリット
- 調子こいてprototype継承しまくってると継承関係複雑すぎてやばいことになる
例えばArrayオブジェクトはObject.prototype -> Array.prototype -> 生成されたArrayオブジェクト
っていうふうに継承をしてて、どんどん親のクラスを追いかけていけるけど
これをもし自作のprototypeオブジェクトを複数回継承してたりしてると、どえらいことになる。
この辺は、はてなインターンのhitodeさんのjs講義資料で触れていて
再度読み直すと勉強になりすぎてやばかった。
まとめ
ただググって記事を読んでいても
頭で理解した気になって、ちゃんと理解できてないタイプなので、
こうやって言語化してアウトプットすると思考が整理されてよかった。
もしかしたらこの記事の内容も間違っているとこがあるかもしれないけれど
そこは先輩たち猛者が指摘してくれることを期待しています。よろしくお願いします。
小さなことからコツコツと。
ありがとう西川きよし。