ボクココ

個人開発に関するテックブログ

JavaScript 〜オブジェクトまとめ〜

最近は英語の勉強ばっかで疲れるわ―。ってことで息抜きにプログラミングの勉強。桁違いの楽しさ!w
今までモヤモヤしていた所をすっきりさせた時に一種の解放感を味わえます。今度はjQueryの勉強をもっとやって、このサイト
http://yakinikunotare.boo.jp/orebase/index.php?Javascript%2FjQuery%2F%C6%C9%A4%E0001
ソースコードリーディングにチャレンジしたい! 他人の素晴らしいコードを見ると自分の欠点がよくわかるって言われてますよね。
ところで、JavaScriptの文法は大体分かってきましたが、一部いまだに曖昧な所があります。
・クロージャの変数の仕組み(本には「本当の変数」とかいう表現があり、曖昧)
・thisの場所による挙動の変動
ここら辺は先生に質問してみるのが手っ取り早そうだな。


んじゃいつも通り行きます!


オブジェクトの定義
JavaScriptオブジェクト指向はプロトタイプベースのオブジェクト指向と呼ばれる。
プロトタイプメソッド+プロパティはクラスである。
コンストラクタ プロパティとメソッド
//クラスの定義
var Member = function(first,last){
this.first=first;
this.last=last;
this.getName=function(){
return this.first + this.last;
}
}
var men = new Member('hom','kimi');
//メソッドの追加
mem.getReverseName = function(){
return this.last+this.first;
}
document.writeln(men.getName()); //homkimi
document.writeln(men.getReverseName()); //kimihom

var women = new Member('hom','ko');
document.writeln(women.getReverseName()); //オブジェクトでサポートされていないプロパティまたはメソッドです

同一のクラスを元に生成されたインスタンスで会っても、それぞれが持つメンバは同一であるとは限らない

コンストラクタの問題点とプロトタイプ
コンストラクタでメソッドを追加すると、メソッドの数に比例して無駄なメモリを消費する欠点がある。
先ほどの例ではmen,womenそれぞれにgetNameメソッドがいちいちコピーされてしまっている。
そこで、prototypeというプロパティを用意する。
Member.prototype.getName=function(){
return this.first+this.last;
};
プロトタイプオブジェクトでプロパティを設定することも可能。
var Member = function(){};
Member.prototype.sex='male';

var mem1 = new Member();
var mem2 = new Member();
document.writeln(mem1.sex+','+mem2.sex); //male,male
mem2.sex='female'; //インスタンス自身がsexプロパティを持つようにする 「隠蔽する」
document.writeln(mem1.sex+','+mem2.sex); //male,female
オブジェクトリテラルを利用して複数のプロトタイプを定義する
Member.prototype = {
getName: function(){},
toString: function(){}
};

オブジェクトの継承 プロトタイプチェーン
var Animal = function(){};
Animal.prototype.walk = function(){ return 'tokotoko';}
var Dog = function(){};
Dog.prototype = new Animal(); //DogクラスのプロトタイプにAnimalクラスのインスタンスを登録!

Dog.prototype.bark = function(){return 'wanwan';};

var d = new Dog();
document.writeln(d.walk()+d.bark();) //tokotokowanwan
ここのwalkメソッドはDogインスタンス→Dogクラス→Animalインスタンス→Animalクラスを伝って探していく。
Animalクラスのプロトタイプでようやく見つかるので実行できる。
このようなプロトタイプの連なりをプロトタイプチェーンと呼ぶ。

クラスライクな継承のしくみ
//initializeBase(現在のクラス,親クラス,引数配列)
function initializeBase(derive,base,baseArgs){
base.apply(derive,baseArgs); //基底クラスのコンストラクタを呼び出す
//基底クラスで定義されたメンバを、派生クラスでも使えるようにコピーする
for(prop in base.prototype){
var proto = derive.constructor.prototype; //deriveにはインスタンス(this)が入っているので、
//コンストラクタ関数(specialmember)のプロトタイプオブジェクトに入れるよう指示する
if(!proto[prop]){
proto[prop] = base.prototype[prop];
}
}
}

var Member = function(first,last){
this.first=first;
this.last=last;
}
Member.prototype.getName=function(){
return this.first+this.last;
};

var SpecialMember = function(first,last,role){
initializeBase(this,Member,[first,last]);
this.role=role;
}
SpecialMember.prototype = {
isAdministrator: function(){ return (this.role == 'Administrator');},
getName: function(){return Member.prototype['getName'].apply(this,[])+this.role;} //親の機能+追加機能
}

var mem = new SpecialMember('hom','kimi','Administrator');
document.writeln('mem.getName()); //homkimi
document.writeln('mem.isAdministrator()'); //true