More Related Content Similar to Javascripでオブジェクト指向 (20) Javascripでオブジェクト指向4. 4.JavaScriptのオブジェクトは、他言語でいう連想配列
Javascriptでは、連想配列を
var arrayObj = { obire : 尾びれだよ。 };
と記述できる。
これをオブジェクトリテラルと呼ぶよ。
実は、これがオブジェクトになる。
これをオブジェクト指向的に
アクセスするには、
console.log(arrayObj. obire );
と書くことができるよ。
5. 5.ドット演算子でも配列的にでもアクセスすることもできる。
console.log(arrayObj. obire );
↑の様にアクセスすることができれば
また、以下の様にアクセスすることもできる。
console.log(arrayObj[ obire ]);
↑おなじみ連想配列的アクセス。
この、オブジェクトであり連想配列でもあるという
点は、javascriptの言語仕様なので
そうなんだとおぼえるしかないちょ。
6. 6.ベースのインスタンスができたよ。
これに、尾びれ・背びれを色々つけたしていくよ。
javascriptで尾びれ・背びれをつけていくには
ベースオブジェクトが必要。これは用意済み。
じゃあ、尾びれの付け方をみてみるよ。
var MainClass = function (){ };
これは、javascriptで非常にベターなユーザー定義関数の
定義方法、これを関数リテラルと呼ぶよ。
?オブジェクトに尾びれをつける(拡張する)のになぜ
関数を定義するんだい?
8. 8.とりあえずカンストラクタを使って拡張してみよう。
var MainClass = function (){
console.log( コンストラクタ );
};
まず、カンストラクタを作る。
カンストラクタそのものは基本はユーザー定義関数と
同じ定義方法だよ。
ただreturnで値を返してはいけないよ。
そして、ここでMainClassという変数に無名関数が
代入されているわけだけど、javascriptだと
関数はオブジェクトなんだよね。
そう。関数オブジェクト。
9. 9.関数オブジェクト?関数がオブジェクト?
関数はオブジェクトなんだよ。だからね、
MainClass.addProperty = プロパティの動的追加 ;
↑こんなことが出来る。これどういう動きをするのかというと
console.log(MainClass.addProperty);
ってすると「プロパティの動的追加」と出力される。
さらに、
MainClass();
とすると、もちろん関数としても実行される。
10. 10.関数オブジェクトは必ずprototypeプロパティを持つ。
関数はオブジェクトと前述した。
つまり、関数は一般的なオブジェクトと同一で
プロパティを持つことができる。先に述べた
addPropertyプロパティのように。
その関数オブジェクトは必ず【prototype】という
プロパティを持つ。絶対にね。
そう!ここで初めてプロトタイプベースのプロトタイプという
キーワードが出現する。
17. 17.もう一度、newしよう。
var subObj = new MainClass();
今度の【subObj】には元々のベースにある
プロトタイプオブジェクトと関数コンストラクタ内で記述した
初期化の内容が反映されている。つまり
console.log(subObj.sebire);
//=> 背びれだよ
console.log(subObj.message);
//=> 大量だぜおい!!!
が出力される。
18. 18.拡張方法は、2通り。
前頁より、特定のオブジェクトをベースに、
拡張したオブジェクトを作成するためには
関数コンストラクタの中に初期化式として記述するか。
あるいは、生成後のオブジェクトに直接動的に
プロパティを追加してくか。の2通りが存在する。
おそらく基本は前者、一般的なクラスベース見たく
拡張できるのでその方が、プロトタイプベースといえど
扱いやすいと思う。
そして、後者のように動的に追加したプロパティを
19. 19.javascriptにおけるオーバーライド。
javascriptでの継承において
オーバーライドはどのような仕様なのか?
先ほど、拡張したオブジェクト【subObj】の
subObj.obire = あ!尾びれじゃねえ、エラだった ;
上記の様に代入する(オーバーライド)とするとどうなる?
console.log(subObj.obire);
//=> あ!尾びれじゃねえ、エラだった
と出力される。
が、継承元のオブジェクト・・つまり【arrayObj】は
20. 20.継承もとのベースオブジェクトは読み出し専用。
javascriptでの継承において
オーバーライドは常に上書きされる。
しかし、その場合ベースのプロトタイプオブジェクトは
変更が反映されず、オーバーライドを行ったオブジェクト
そのものに、独自プロパティとして新たに同名のプロパティが
追加される。
つまりこの場合、【subObj】には【obire】というプロパティが
正確には2つ存在することになる。
【尾びれだよ】という値と【あ!尾びれじゃねえ、エラだった】
22. 22.delete 演算子はオブジェクトのプロパティを削除する。
delete ( subObj.obire);
という記述をしてやることで【subObj】の独自プロパティを
削除することになり、結果【subObj.obire】は
当初のプロトタイプオブジェクトの値を参照するようになる。
ただし、この場合
継承元のプロトタイプオブジェクトから引き継いだものは
削除することはできない。
23. 23.総まとめだよ。
①javascriptのオブジェクトは連想配列と同義だよ。
var arrayObj = { key_01 : value_01 };
console.log(arrayObj.key_01);
console.log(arrayObj[ key_01 ]);
の二通りの参照方法があるよ。
②プロトタイプ継承を行うためにはベースのオブジェクトが必要。
そのためには、関数を関数コンストラクタとして用いることで
特定のオブジェクトを元に拡張オブジェクトを作成できるよ。
var MainClass = function(){
this.addProperty = 拡張プロパテイ ;
24. 24.総まとめだよ。
③関数はオブジェクトだよ。関数オブジェクトは必ず
prototypeプロパティを持つ。このprototypeオブジェクトに
代入した任意のオブジェクトが
ベースのオブジェクトになるよ。
MainClass.prototype =arrayObj;
④new キーワードで新たな拡張オブジェクトを作成する。
var subObj = new MainClass();
このオブジェクト【subObj】は、プロトタイプオブジェクトから
継承した【key_01】とコンストラクタ内に記述した
26. 26.Functionコンストラクタとは?
その名の通り関数オブエジェクトを作るための
関数コンストラクタ。
javascriptは内部的にこのFunctionコンストラクタを用いて
関数定義を行なっていると思って良い。
例えば、
function TestClass(){}
も
var TestClass = function(){}
も内部でFunctionコンストラクタを呼んでいると思ってよい。
30. 30.Function関数のprototypeプロパティは関数オブジェクトのベース
Function関数のprototypeプロパティは、一般の
関数オブジェクトの元になるオブジェクトなんだ。
つまり、Function.prototypeにプロパティを更に
追加することによってその他の関数オブジェクトにも
反映させることができるんだ。
例を見てみよう。
Function . prototype . addProperty = 追加プロパティ ;
var TestClass = function (){ console.log( コンストラクタ );};
と、したとしようか。
31. 31.Function関数のprototypeプロパティは
関数オブジェクトに反映される。
Function . prototype . addProperty = 追加プロパティ ;
var TestClass = function (){ console.log( コンストラクタ );};
関数オブジェクトはFunction.prototypeを継承するので
この場合、生成されたTestClassもaddPropertyプロパティを
持つことになる。試してみよう。
console.log(TestClass.addProperty);
// => 追加プロパティ
と出力される。
32. 32.Function . A とFunction .prototype . Aは同一。
ちょっと、ややこしいが関数オブジェクトはFunctionクラスの
インスタンスだと言った。
関数オブジェクトを生成する方法は複数あるがクラスベースで
擬似的に考えた場合、Function関数をnewして生成された
関数オブジェクトはFunction . prototypeを継承することになる。
これは例えば、MainClass関数をnewした場合、生成された
オブジェクトがMainClass.prototypeを継承することと同義だ。
関数オブジェクトがFunction.prototypeを継承するなら
Function関数そのものはどうなるのだろうか?
33. 33.Function . A == Function .prototype . Aな関係。
たとえば、Function.prototype. A= A ;としたとする。
この処理は関数オブジェクトに反映される。
つまりFunctionという関数オブジェクトにも反映される。
console.log(Function.prototype.A);
とすると【A】が出力される。さらに、
console.log(Function.A);
としても【A】が出力される。
ちょっと自己参照な実装がされているようだ。
Functionクラスのちょっと変わった一面だったね。