Javascriptの基本; prototypeオブジェクトによる拡張
1年ほど前に「Javascriptの基本」と題して、いくつかのログを残した。少し整理しようかと思って見直したところ、proptotypeオブジェクトを使った関数オブジェクトの拡張を書きもらしていた。サンプルを作ったので、覚書きとして残しておこう。
まず、最初のサンプルは、prototypeオブジェクトに、関数列をオブジェクト・リテラルの形式で拡張する。
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>prototypeによるオブジェクトの継承と拡張</title> <script type="text/javascript">// <![CDATA[ var obj1 = function(){ // --- (1) ひな型の設定 this.key1='value1'; this.func1 = function(){ alert('func1; ' + this.key1); }; this.func2 = function(){ alert('func2!!'); }; return this; }; var obj3 = new obj1(); obj3.func1(); obj3.func2(); /* * 継承と拡張 */ obj1.prototype = { 'func1' : function(){ // --- (4) overrideのテスト alert('func1 override; ' + this.key1); }, 'func3' : function(){ // --- (5) 拡張のテスト alert('func3!!'); } } var obj4 = new obj1(); // prototypeを設定したobj1をインスタンス化する。 obj4.func1(); // --- (6) func1は(prototypeオブジェクトではなく)obj1に存在するので、そちらが優先される。 obj4.func2(); // --- (7) ひな型をたどる obj4.func3(); // --- (8) 拡張した関数 // ]]></script> </head> <body> </body> </html>
「継承と拡張」以下の部分でobj1のprototypeオブジェクトに対して、func1, func2という関数を設定している。obj1を直接拡張しているような形式のため、静的な拡張に感じられる。この場合、funcは、obj1そのものに定義されているので、obj1のインスタンスであるobj4からfunc1を呼び出した場合には、obj1に定義されているfunc1が呼び出される。
次は、一見似た例だが、func1をオーバーライドしている。
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>prototypeによるオブジェクトの継承と拡張</title> <script type="text/javascript">// <![CDATA[ var obj1 = function(){ // --- (1) ひな型の設定 this.key1='value1'; this.func1 = function(){ alert('func1; ' + this.key1); }; this.func2 = function(){ alert('func2!!'); }; return this; }; var obj3 = new obj1(); obj3.func1(); obj3.func2(); /* * 継承と拡張 */ var obj2 = function() {}; // 箱をつくる。 obj2.prototype = new obj1(); // obj2のprototype(属性)に、obj1の「インスタンス」を設定する。 obj2.prototype.func1 = function(){ // --- (4) override alert('func1 override; ' + this.key1); }; obj2.prototype.func3 = function(){ // --- (5) 拡張 alert('func3!!'); }; var obj4 = new obj2(); // prototypeとして定義したobj2をインスタンス化する。 obj4.func1(); // --- (6) func1はobj2のprototypeに定義されているので、(4)でoverrideされる obj4.func2(); // --- (7) ひな型をたどる obj4.func3(); // --- (8) 拡張した関数 // ]]></script> </head> <body> </body> </html>
拡張・継承という意味では、func2, func3は期待通りの結果を返す。
参考;@IT「第4回 JavaScriptでオブジェクト指向プログラミング」