[a 3]ssjsでも使える!javascriptでオブジェクト指向プログラミング入門

98
www.ktrick.com A-3SSJSでも使える!Javascriptオブジェクト指向プログラミング入門 KTrick 合同会社 代表 田付 和慶

Upload: kazunori-tatsuki

Post on 08-Jul-2015

1.630 views

Category:

Technology


1 download

DESCRIPTION

XPagesDay 2014 (2014/11/18) 【A-3】「SSJSでも使える!Javascriptでオブジェクト指向プログラミング入門」で使用したスライドになります。

TRANSCRIPT

Page 1: [A 3]SSJSでも使える!Javascriptでオブジェクト指向プログラミング入門

www.ktrick.com

【A-3】SSJSでも使える!Javascriptで

オブジェクト指向プログラミング入門

KTrick 合同会社 代表 田付 和慶

Page 2: [A 3]SSJSでも使える!Javascriptでオブジェクト指向プログラミング入門

• 田付 和慶 (たつき かずのり)

• ケートリック合同会社 代表

• 米国で7年間、IBM Connect (旧Lotusphere) のオンラインソリューションを XPages で開発してきました。

• 会社のスローガン「若い力を集結させた IBM 技術者集団をめざす!」 (特にICS)

自己紹介

Page 3: [A 3]SSJSでも使える!Javascriptでオブジェクト指向プログラミング入門

XPagesでの開発を難しく感じる

原因って何でしょう?

Page 4: [A 3]SSJSでも使える!Javascriptでオブジェクト指向プログラミング入門

1つはやっぱりJavascript?

しかもクライアントサイド?

サーバーサイド?

いきなり2つも覚えろとか・・・(T_T)

Page 5: [A 3]SSJSでも使える!Javascriptでオブジェクト指向プログラミング入門

最近ではネットでJavascriptのサンプル

漁ってみると、

こんなんだったり、

var func1 = function(){

alert("hello!");

}

こんなんだったり、

var myButton = new Button({

label: "Show me!",

onClick: function(){

myDialog.set("content", “Hello!");

myDialog.show();

}

}, "progbutton").startup();

Page 6: [A 3]SSJSでも使える!Javascriptでオブジェクト指向プログラミング入門

Javascriptっていえば、

function func1(param){

alert(param);

}

こうじゃないの?

なんで function が後ろに来ちゃうの?

Page 7: [A 3]SSJSでも使える!Javascriptでオブジェクト指向プログラミング入門

他にも、こういったの見たことありませんか?

( function() {

//関数の中身・・・

}() );

おいおい ちょっと、、、カッコ 多くないか?

これ、最後のカッコ本当にいるの???

Page 8: [A 3]SSJSでも使える!Javascriptでオブジェクト指向プログラミング入門

お作法だからしかたないんだ…

で諦めていませんか?

Page 9: [A 3]SSJSでも使える!Javascriptでオブジェクト指向プログラミング入門

このセッションでは

そういった

Javascriptの構造を少し紐解いて

言語への理解を深くしてもらえたらと思っています。

Page 10: [A 3]SSJSでも使える!Javascriptでオブジェクト指向プログラミング入門

オブジェクト指向プログラミング

そもそも、オブジェクト指向プログラミング(OOP)をすると

なんのメリットがあるのでしょうか?

Page 11: [A 3]SSJSでも使える!Javascriptでオブジェクト指向プログラミング入門

OOPの概念や仕組みについて触れだすとこのセッションをフルに使っても時間が足らないので割愛しますが、

主なメリットとして・プログラムの可読性が高まる

・プログラムの再利用がしやすい

・拡張や仕様変更に強くなる

結果、

テストにかかる時間を減らせ、デスマーチの確率を減らせる。

あと、オブジェクト指向が分かっているとなんだかカッコいい、という風潮がある

などなど

Page 12: [A 3]SSJSでも使える!Javascriptでオブジェクト指向プログラミング入門

オブジェクト指向

この言葉から

なにを思い浮かべますか?

Page 13: [A 3]SSJSでも使える!Javascriptでオブジェクト指向プログラミング入門

オブジェクト指向プログラミング

クラス 移譲

オーバーロードポリモーフィズム

Java

C++抽象クラス

C#オーバーライド

継承派生クラス

インスタンス

UML

Page 14: [A 3]SSJSでも使える!Javascriptでオブジェクト指向プログラミング入門

オブジェクト指向プログラミングの経験者なら

「クラス」

を真っ先に思いうかべた人もいると思います。

Page 15: [A 3]SSJSでも使える!Javascriptでオブジェクト指向プログラミング入門

では、

Javascriptにもクラスってあるの?

Page 16: [A 3]SSJSでも使える!Javascriptでオブジェクト指向プログラミング入門

ないです。諸説あり

Page 17: [A 3]SSJSでも使える!Javascriptでオブジェクト指向プログラミング入門

クラスがなくてどうやって

オブジェクト指向プログラミング(OOP)するの?

Page 18: [A 3]SSJSでも使える!Javascriptでオブジェクト指向プログラミング入門

その答えは…

Page 19: [A 3]SSJSでも使える!Javascriptでオブジェクト指向プログラミング入門

プロトタイプチェイン

Page 20: [A 3]SSJSでも使える!Javascriptでオブジェクト指向プログラミング入門

そもそも、Javascriptにあるのは

オブジェクト のみ

Page 21: [A 3]SSJSでも使える!Javascriptでオブジェクト指向プログラミング入門

オブジェクト指向なんだから、

オブジェクトがあればいいのです!(強気)

クラスなんて飾りです!

クラスベースの言語にはそれがわからんのです!

(錯乱)

Page 22: [A 3]SSJSでも使える!Javascriptでオブジェクト指向プログラミング入門

子Class (型)

そもそも、クラスってこんなの

親Class (型)

Object (実体)

Object (実体)

Object (実体)

NEW

NEW

NEW

クラスでオブジェクトの「型」をあ

らかじめ定義しておき、そのクラス

をもとに実体を生成して利用する。

こうすることで、クラスがもつ機能

(関数)や属性(変数)を持った実

体が量産出来る。

Page 23: [A 3]SSJSでも使える!Javascriptでオブジェクト指向プログラミング入門

クラスを持たない

Javascriptでは…

Page 24: [A 3]SSJSでも使える!Javascriptでオブジェクト指向プログラミング入門

こんなイメージ

Object (実体)

Object (実体)

Object (実体)

Object (実体)Delegate

Delegate

Delegate

オブジェクト(実体)を数珠つな

ぎのように繋げて、

オブジェクト自身が知らない関数

や変数への呼び出しがあれば、繋

がりのある別のオブジェクトに移

譲(Delegate)することで見つか

るまで遡っていくイメージ。

プロトタイプチェイン

Object (実体)

Delegate

Page 25: [A 3]SSJSでも使える!Javascriptでオブジェクト指向プログラミング入門

このように、

Javascriptではクラスではなくプロトタイプチェインという機構を使い

オブジェクト指向プログラミングを実装しているので、

プロトタイプベースオブジェクト指向言語

なんて呼ばれています。

Page 26: [A 3]SSJSでも使える!Javascriptでオブジェクト指向プログラミング入門

それでは、ここからは実際のコードで説明をしていきます。

※基本的にクライアントサイドJavascriptとして考えて下さい。

サーバーサイドJavascriptではalert() 等できないためですが、基本の考え方は同じです。

Page 27: [A 3]SSJSでも使える!Javascriptでオブジェクト指向プログラミング入門

まずは基本。

Page 28: [A 3]SSJSでも使える!Javascriptでオブジェクト指向プログラミング入門

Objectの作り方

var obj = { };

空っぽのオブジェクトが出来ました。

Page 29: [A 3]SSJSでも使える!Javascriptでオブジェクト指向プログラミング入門

Objectの構造

var obj = {

key: value

};

プロパティ(キーと値の組み合わせ)

単純ですがこれだけです。

var obj = {

name : “Apple”,

size : 500

};

alert(obj.name);

(例)

Page 30: [A 3]SSJSでも使える!Javascriptでオブジェクト指向プログラミング入門

var obj = {

func1 : function( ) {alert(“hoge”); }

};

obj.func1(); // Output “hoge”

Javascriptでは関数も「値」(第一級オブジェクト)

var func = function( ){};

だから変数に代入できます。

そして変数から変数へコピーなどの操作もできます。

(例)オブジェクトのプロパティにも代入できます。

Page 31: [A 3]SSJSでも使える!Javascriptでオブジェクト指向プログラミング入門

どんどんいきましょう。

いよいよ プロトタイプチェインの説明です。

JavascriptのOOPの真骨頂

Page 32: [A 3]SSJSでも使える!Javascriptでオブジェクト指向プログラミング入門

Javascriptのプロトタイプチェインを学ぼうとするとき

しばしば以下の2つのキーワードが登場します。

➲ __proto__ ➲prototype

この2つの意味の違いをしっかりと理解することが

Javascript OOPを理解する上でとても重要になります

Page 33: [A 3]SSJSでも使える!Javascriptでオブジェクト指向プログラミング入門

➲ __proto__

Page 34: [A 3]SSJSでも使える!Javascriptでオブジェクト指向プログラミング入門

__proto__

・Javascriptでは全てのオブジェクトは

内部プロパティ[[Prototype]]を持つ

という仕様があります。

とは言いつつ、実際には__proto__というプロパティでプログラム

から扱える実装が多い。(ChromeやFirefox)

内部プロパティと言っているので、本来は外から参照出来ない性質のもの

Page 35: [A 3]SSJSでも使える!Javascriptでオブジェクト指向プログラミング入門

こんなイメージ

Object (実体)

Object (実体)

Object (実体)

Object (実体)Delegate

Delegate

Delegate

__proto__

__proto__

__proto__

__proto__

Page 36: [A 3]SSJSでも使える!Javascriptでオブジェクト指向プログラミング入門

コードで確認 (__proto__が使えるchrome,firefoxで動きます)

「It is Apple」が出力されます

var obj = {

name : “none”,

callMe : function() { alert(“It is ” + this.name); }

};

var objApple = { name : “Apple”};

objApple.__proto__ = obj;

var objBlackbox = { };

objBlackbox.__proto__ = objApple;

objBlackbox.callMe();

空っぽなのに

Page 37: [A 3]SSJSでも使える!Javascriptでオブジェクト指向プログラミング入門

コードを順番に確認(1)

「It is Apple」が出力されます

オブジェクトを生成。

name,

callMe

のプロパティを持つ

objApple オブジェクトを生成。

nameプロパティに”Apple”を持つ

objBlackbox オブジェクトを生成。

プロパティはなにも持たない。

var obj = {

name : “none”,

callMe : function() { alert(“It is ” + this.name); }

};

var objApple = { name : “Apple”};

objApple.__proto__ = obj;

var objBlackbox = { };

objBlackbox.__proto__ = objApple;

objBlackbox.callMe();

Page 38: [A 3]SSJSでも使える!Javascriptでオブジェクト指向プログラミング入門

コードを順番に確認(2)

オブジェクトを生成。

name,

callMe

のプロパティを持つ

objApple オブジェクトを生成。

nameプロパティに”Apple”を持つ

objBlackbox オブジェクトを生成。

プロパティはなにも持たない。

objApple.__proto__に objを代入

var obj = {

name : “none”,

callMe : function() { alert(“It is ” + this.name); }

};

var objApple = { name : “Apple”};

objApple.__proto__ = obj;

var objBlackbox = { };

objBlackbox.__proto__ = objApple;

objBlackbox.callMe();

Page 39: [A 3]SSJSでも使える!Javascriptでオブジェクト指向プログラミング入門

コードを順番に確認(2)

オブジェクトを生成。

name,

callMe

のプロパティを持つ

objApple オブジェクトを生成。

nameプロパティに”Apple”を持つ

objBlackbox オブジェクトを生成。

プロパティはなにも持たない。

objApple.__proto__に objを代入

objBlackbox.__proto__にobjAppleを代入

var obj = {

name : “none”,

callMe : function() { alert(“It is ” + this.name); }

};

var objApple = { name : “Apple”};

objApple.__proto__ = obj;

var objBlackbox = { };

objBlackbox.__proto__ = objApple;

objBlackbox.callMe();

Page 40: [A 3]SSJSでも使える!Javascriptでオブジェクト指向プログラミング入門

コードで確認(メソッドの確認)

var obj = {

name : “none”,

callMe : function() { alert(“It is ” + this.name); }

};

var objApple = { name : “Apple”};

objApple.__proto__ = obj;

var objBlackbox = { };

objBlackbox.__proto__ = objApple;

objBlackbox.callMe();

Page 41: [A 3]SSJSでも使える!Javascriptでオブジェクト指向プログラミング入門

コードで確認(メソッドの確認)

(1) objBlackboxにはcallMe() メソッドがない

var obj = {

name : “none”,

callMe : function() { alert(“It is ” + this.name); }

};

var objApple = { name : “Apple”};

objApple.__proto__ = obj;

var objBlackbox = { };

objBlackbox.__proto__ = objApple;

objBlackbox.callMe();

Page 42: [A 3]SSJSでも使える!Javascriptでオブジェクト指向プログラミング入門

コードで確認(メソッドの確認)

(1) objBlackboxにはcallMe() メソッドがない

(2)__proto__にあるオブジェクトを検索 (objApple)

var obj = {

name : “none”,

callMe : function() { alert(“It is ” + this.name); }

};

var objApple = { name : “Apple”};

objApple.__proto__ = obj;

var objBlackbox = { };

objBlackbox.__proto__ = objApple;

objBlackbox.callMe();

Page 43: [A 3]SSJSでも使える!Javascriptでオブジェクト指向プログラミング入門

コードで確認(メソッドの確認)

(1) objBlackboxにはcallMe() メソッドがない

(3) objAppleにもcallMe() メソッドがない

(2)__proto__にあるオブジェクトを検索 (objApple)

var obj = {

name : “none”,

callMe : function() { alert(“It is ” + this.name); }

};

var objApple = { name : “Apple”};

objApple.__proto__ = obj;

var objBlackbox = { };

objBlackbox.__proto__ = objApple;

objBlackbox.callMe();

Page 44: [A 3]SSJSでも使える!Javascriptでオブジェクト指向プログラミング入門

コードで確認(メソッドの確認)

(1) objBlackboxにはcallMe() メソッドがない

(3) objAppleにもcallMe() メソッドがない

(2)__proto__にあるオブジェクトを検索 (objApple)

(4)__proto__にあるオブジェクトを検索 (obj)

var obj = {

name : “none”,

callMe : function() { alert(“It is ” + this.name); }

};

var objApple = { name : “Apple”};

objApple.__proto__ = obj;

var objBlackbox = { };

objBlackbox.__proto__ = objApple;

objBlackbox.callMe();

Page 45: [A 3]SSJSでも使える!Javascriptでオブジェクト指向プログラミング入門

コードで確認(メソッドの確認)

(1) objBlackboxにはcallMe() メソッドがない

(3) objAppleにもcallMe() メソッドがない

(2)__proto__にあるオブジェクトを検索 (objApple)

(5) objにcallMe() メソッドを発見!

(4)__proto__にあるオブジェクトを検索 (obj)

var obj = {

name : “none”,

callMe : function() { alert(“It is ” + this.name); }

};

var objApple = { name : “Apple”};

objApple.__proto__ = obj;

var objBlackbox = { };

objBlackbox.__proto__ = objApple;

objBlackbox.callMe();

Page 46: [A 3]SSJSでも使える!Javascriptでオブジェクト指向プログラミング入門

コードで確認(属性の確認)

(1) callMe() メソッドが呼ばれます

var obj = {

name : “none”,

callMe : function() { alert(“It is ” + this.name); }

};

var objApple = { name : “Apple”};

objApple.__proto__ = obj;

var objBlackbox = { };

objBlackbox.__proto__ = objApple;

objBlackbox.callMe();

Page 47: [A 3]SSJSでも使える!Javascriptでオブジェクト指向プログラミング入門

コードで確認(属性の確認)

(1) callMe() メソッドが呼ばれます

(2) name 属性を参照※this は自身のオブジェクトを

意味していますvar obj = {

name : “none”,

callMe : function() { alert(“It is ” + this.name); }

};

var objApple = { name : “Apple”};

objApple.__proto__ = obj;

var objBlackbox = { };

objBlackbox.__proto__ = objApple;

objBlackbox.callMe();

Page 48: [A 3]SSJSでも使える!Javascriptでオブジェクト指向プログラミング入門

コードで確認(属性の確認)

(1) callMe() メソッドが呼ばれます

(2) name 属性を参照※this は自身のオブジェクトを

意味しています

(3) objBlackboxにはname属性がない

var obj = {

name : “none”,

callMe : function() { alert(“It is ” + this.name); }

};

var objApple = { name : “Apple”};

objApple.__proto__ = obj;

var objBlackbox = { };

objBlackbox.__proto__ = objApple;

objBlackbox.callMe();

Page 49: [A 3]SSJSでも使える!Javascriptでオブジェクト指向プログラミング入門

コードで確認(属性の確認)

(1) callMe() メソッドが呼ばれます

(4)__proto__にあるオブジェクトを検索 (objApple)

(2) name 属性を参照※this は自身のオブジェクトを

意味しています

(3) objBlackboxにはname属性がない

var obj = {

name : “none”,

callMe : function() { alert(“It is ” + this.name); }

};

var objApple = { name : “Apple”};

objApple.__proto__ = obj;

var objBlackbox = { };

objBlackbox.__proto__ = objApple;

objBlackbox.callMe();

Page 50: [A 3]SSJSでも使える!Javascriptでオブジェクト指向プログラミング入門

コードで確認(属性の確認)

(1) callMe() メソッドが呼ばれます

(5) objAppleにnameを発見!

(4)__proto__にあるオブジェクトを検索 (objApple)

(2) name 属性を参照※this は自身のオブジェクトを

意味しています

(3) objBlackboxにはname属性がない

var obj = {

name : “none”,

callMe : function() { alert(“It is ” + this.name); }

};

var objApple = { name : “Apple”};

objApple.__proto__ = obj;

var objBlackbox = { };

objBlackbox.__proto__ = objApple;

objBlackbox.callMe();

Page 51: [A 3]SSJSでも使える!Javascriptでオブジェクト指向プログラミング入門

コードで確認(属性の確認)

(1) callMe() メソッドが呼ばれます

(5) objAppleにnameを発見!

(4)__proto__にあるオブジェクトを検索 (objApple)

(2) name 属性を参照※this は自身のオブジェクトを

意味しています

(3) objBlackboxにはname属性がない

(6) objにもname属性はあるが、参照されない

var obj = {

name : “none”,

callMe : function() { alert(“It is ” + this.name); }

};

var objApple = { name : “Apple”};

objApple.__proto__ = obj;

var objBlackbox = { };

objBlackbox.__proto__ = objApple;

objBlackbox.callMe();

Page 52: [A 3]SSJSでも使える!Javascriptでオブジェクト指向プログラミング入門

このように自オブジェクトにない機能(関数)、属性(変数)に対して__proto__を通して移譲(Delegate)しながらキーが見つかるまで検索していく仕組み…

これが

プロトタイプチェイン

Object (実体)

Object (実体)

Object (実体)

Object (実体)

Delegate

Delegate

Delegate

ない

ない

ない

あった

Page 53: [A 3]SSJSでも使える!Javascriptでオブジェクト指向プログラミング入門

__proto__ の役割、ご理解頂けたでしょうか?

Page 54: [A 3]SSJSでも使える!Javascriptでオブジェクト指向プログラミング入門

ん???、ちょっと待って下さい

__proto__ (別名:[[Prototype]])は内部プロパティだから本来、外部から扱えないもの。

じゃあ、理解できてもこんなコード使えないじゃないか?

objApple.__proto__ = obj;

と思いませんか?

Page 55: [A 3]SSJSでも使える!Javascriptでオブジェクト指向プログラミング入門

はい、使わないで下さい!

Page 56: [A 3]SSJSでも使える!Javascriptでオブジェクト指向プログラミング入門

実は内部的な動作を理解してもらいやすくするために

こんなコードを書きましたが、同等の処理をさせる別の記述があります。

var objApple = { name : “Apple”};

objApple.__proto__ = obj;

Page 57: [A 3]SSJSでも使える!Javascriptでオブジェクト指向プログラミング入門

new演算子 です

(例)今までのサンプルコードもOOP風に書き換えが必要になってきます。

var obj = new Frout(“Apple”);

このコードに関して

後で解説します。

var Frout = function( pname ) {

this.name = pname;

}

Frout.prototype.callMe = function() { alert(“It is ” + this.name); };

var objApple = new Frout(“Apple”);

Page 58: [A 3]SSJSでも使える!Javascriptでオブジェクト指向プログラミング入門

➲ prototype

わすれちゃいけない、もう一つのキーワード「prototype」

__proto__でプロトタイプチェーンの理解出来たし、説明いらない、なんて言わないで下さい。

違いを理解するのがとっても大切!

Page 59: [A 3]SSJSでも使える!Javascriptでオブジェクト指向プログラミング入門

prototype

・Javascriptでは、

全ての関数オブジェクトはprototype プロパティを持つ

という仕様があります。

ん? 関数オブジェクト?? 初登場です。でも安心してください、もう知ってます。

Page 60: [A 3]SSJSでも使える!Javascriptでオブジェクト指向プログラミング入門

関数オブジェクトとは

実は、前述していました。関数であっても「値」として扱える(第一級オブジェクト)

というやつです。

var func = function( ){};

こういうの

Page 61: [A 3]SSJSでも使える!Javascriptでオブジェクト指向プログラミング入門

全ての関数オブジェクトには prototype プロパティ を持ちます。

改めまして、

例えば、var func = function( ){};

alert( func.prototype );

とすると、undefinedとはならず、prototype プロパティが存在することが確認できます。

でも、関数オブジェクトを定義した直後では、prototypeは何も値を持たない空っぽのオブジェクトを参照しています。

では、これが何に使われるのでしょうか・・・

Page 62: [A 3]SSJSでも使える!Javascriptでオブジェクト指向プログラミング入門

ちょっと前で触れた new 演算子 で、

オブジェクトが生成されるときに使われます!

Page 63: [A 3]SSJSでも使える!Javascriptでオブジェクト指向プログラミング入門

コードで確認

(今までのサンプルコードの書き換え版)

コンストラクタの定義

関数オブジェクトを生成。

name変数は未定義。

Frout オブジェクトのprototype

プロパティにメソッドを追加

new演算子 でobjApple オブジェクトを生成。

objAppleのプロトタイプチェインよりFroutのprototypeを継承

var Frout = function( pname ) {

this.name = pname;

}

Frout.prototype.callMe = function() { alert(“It is ” + this.name); };

var objApple = new Frout(“Apple”);

objApple.callMe(); 「It is Apple」が出力されます。objApple.prototype.callMe()

ではないことに注目

次のスライドで触れます

Page 64: [A 3]SSJSでも使える!Javascriptでオブジェクト指向プログラミング入門

var obj = {};

obj.__proto__ = Frout.prototype;

Frout.apply(obj, arguments );

return obj;

newした時の処理を擬似的に表現すると

var objApple = new Frout(“Apple”);

Page 65: [A 3]SSJSでも使える!Javascriptでオブジェクト指向プログラミング入門

var obj = {};

obj.__proto__ = Frout.prototype;

Frout.apply(obj, arguments );

return obj;

newした時の処理を擬似的に表現すると

(1) オブジェクトを生成

var objApple = new Frout(“Apple”);

Page 66: [A 3]SSJSでも使える!Javascriptでオブジェクト指向プログラミング入門

var obj = {};

obj.__proto__ = Frout.prototype;

Frout.apply(obj, arguments );

return obj;

newした時の処理を擬似的に表現すると

(1) オブジェクトを生成

(2) prototype プロパティを __proto__ に代入

Frout.prototypeにはcallMe メソッ

ドがあります

Frout.prototype.callMe = function() { alert(“It is ” + this.name); };

var objApple = new Frout(“Apple”);

Page 67: [A 3]SSJSでも使える!Javascriptでオブジェクト指向プログラミング入門

var obj = {};

obj.__proto__ = Frout.prototype;

Frout.apply(obj, arguments );

return obj;

newした時の処理を擬似的に表現すると

(1) オブジェクトを生成

(2) prototype プロパティを __proto__ に代入

(3) コンストラクタ関数を実行

コンストラクタとは関数オブジェクト生成時に一度だけ呼び

出される関数

Frout.prototypeにはcallMe メソッ

ドがあります

Frout.prototype.callMe = function() { alert(“It is ” + this.name); };

var objApple = new Frout(“Apple”);

Page 68: [A 3]SSJSでも使える!Javascriptでオブジェクト指向プログラミング入門

var obj = {};

obj.__proto__ = Frout.prototype;

Frout.apply(obj, arguments );

return obj;

newした時の処理を擬似的に表現すると

(1) オブジェクトを生成

(2) prototype プロパティを __proto__ に代入

(3) コンストラクタ関数を実行

コンストラクタとは関数オブジェクト生成時に一度だけ呼び

出される関数

(4) 処理したオブジェクトを返す

Frout.prototypeにはcallMe メソッ

ドがあります

Frout.prototype.callMe = function() { alert(“It is ” + this.name); };

var objApple = new Frout(“Apple”);

Page 69: [A 3]SSJSでも使える!Javascriptでオブジェクト指向プログラミング入門

var obj = {};

obj.__proto__ = Frout.prototype;

Frout.apply(obj, arguments );

return obj;

newした時の処理を擬似的に表現すると

(1) オブジェクトを生成

(2) prototype プロパティを __proto__ に代入

(3) コンストラクタ関数を実行

コンストラクタとは関数オブジェクト生成時に一度だけ呼び

出される関数

(4) 処理したオブジェクトを返す

Frout.prototypeにはcallMe メソッ

ドがあります

Frout.prototype.callMe = function() { alert(“It is ” + this.name); };

var objApple = new Frout(“Apple”);

var objApple = new Frout(“Apple”);

Page 70: [A 3]SSJSでも使える!Javascriptでオブジェクト指向プログラミング入門

__proto__の解説で使ったサンプル

var obj = {};

obj.__proto__ = Frout.prototype;

Frout.apply(obj, arguments );

return obj;

newした時の処理を擬似的に表現した処理

obj を Frout.prototype だと置き換えたらどちらもcallMe() メソッドを持つことに

なることが想像できます。

Frout.prototype.callMe = function() {…};

var obj = {

name : “none”,

callMe : function() { … }

};

var objApple = { name : “Apple”};

objApple.__proto__ = obj;

Page 71: [A 3]SSJSでも使える!Javascriptでオブジェクト指向プログラミング入門

__proto__ と prototype の違い、ご理解頂けたでしょうか?

プロトタイプオブジェクトを格納し、

newされたときに__proto__

に代入されることでプロトタイプチェインを

作り出す。

プロトタイプチェインの検索の仕組みそのもの。

newされたオブジェクトのprototype が自動で格

納される。

__proto__ prototype

積極的に使って行きましょう

概念の理解のために必要。実際はnewとprototypeで実

装させよう

Page 72: [A 3]SSJSでも使える!Javascriptでオブジェクト指向プログラミング入門

では、ちょっと頭の体操

Page 73: [A 3]SSJSでも使える!Javascriptでオブジェクト指向プログラミング入門

Frout オブジェクトの準備で

と記述しましたが、

と書きたくなりませんか? これじゃダメでしょうか?

var Frout = function( name ) {

this.name = name;

}

Frout.prototype.callMe = function() { alert(“It is ” + this.name); };

var Frout = function( name ) {

this.name = name;

this.callMe = function() { alert(“It is ” + this.name); };

}

Page 74: [A 3]SSJSでも使える!Javascriptでオブジェクト指向プログラミング入門

OOPの観点から見ると良くないです

でも、動きます

Page 75: [A 3]SSJSでも使える!Javascriptでオブジェクト指向プログラミング入門

理由:

var Frout = function( name ) {

this.name = name;

this.callMe = function() { alert(“It is ” + this.name); };

}

このコードでは、prototype を使わず、コンストラクタ関数の中で定義されてしまいます。

つまり、

newによりオブジェクトが生成される度にこのメソッド(callMe())も新たに生成されてしまいます。

対照的に、prototype内に定義されたメソッド、変数はプロトタイプチェインの中に入る仕組みに合わせて、

オブジェクトが何度newされても同一のメモリから参照されるという仕組みになっているためメモリ効率がよくなります。

Frout.prototype.callMe = function() { alert(“It is ” + this.name); };

Page 76: [A 3]SSJSでも使える!Javascriptでオブジェクト指向プログラミング入門

応用

Page 77: [A 3]SSJSでも使える!Javascriptでオブジェクト指向プログラミング入門

冒頭で紹介したサンプルコード

カッコばかりのこの関数、いったいどういった動作をするでしょう?

( function() {

//関数の中身・・・

}() );

Page 78: [A 3]SSJSでも使える!Javascriptでオブジェクト指向プログラミング入門

結論を先に述べると、

無名関数を作って即時呼び出し

を行っています。

Page 79: [A 3]SSJSでも使える!Javascriptでオブジェクト指向プログラミング入門

関数オブジェクトが返された直後に、その関数を呼び出している。

即時関数

関数オブジェクトを生成。

( function() {

//関数の中身・・・

}() );

変数で受けていない無名関数。

というなんとも複雑な処理を経ていました。

ページが読み込まれた時、一度だけ処理をする、といった時に使われます。

即時関数には2つある?

//即時関数1(function () {

//関数の中身・・・}());

//即時関数2(function () {

//関数の中身・・・})();

どちらも即時関数として機能しますが、JSLint(http://www.jslint.com/)では前者のコードの方が好ましいようです。

Page 80: [A 3]SSJSでも使える!Javascriptでオブジェクト指向プログラミング入門

応用 その2 …

Page 81: [A 3]SSJSでも使える!Javascriptでオブジェクト指向プログラミング入門

結果は…

var Frout = function( name ) {

this.name = name;

}

Frout.prototype.callMe = function() { alert(“It is ” + this.name); };

var objApple = new Frout(“Apple”);

alert( objApple.name );

private 変数だったら参照できないはず

これってprivate 変数?

protected 変数?public 変数?

OOPと言うのだったらprivate 変数で隠蔽化ぐらいはしたくなりませんか?

Page 82: [A 3]SSJSでも使える!Javascriptでオブジェクト指向プログラミング入門

(当然ながら、)参照できてしまいます orz

でもちょっとまって

Page 83: [A 3]SSJSでも使える!Javascriptでオブジェクト指向プログラミング入門

こんな感じで(魔)改造します

var FroutModel = (function() { // private変数var name = “none";

// コンストラクタvar cls = function(pname){name = pname;};

// public メソッドcls.prototype.callMe = function() {alert("This is "+name);};

return cls;} () );

var Frout = function( name ) {

this.name = name;

}

Frout.prototype.callMe = function() { alert(“It is ” + this.name); };

(魔)改造前

Page 84: [A 3]SSJSでも使える!Javascriptでオブジェクト指向プログラミング入門

var FroutModel = (function() { // private変数var name = “none";

// コンストラクタvar cls = function(pname){name = pname;};

// public メソッドcls.prototype.callMe = function() {alert("This is "+name);};

return cls;} () );

var objApple = new FroutModel(“Apple”);

alert( objApple.name );

objApple.callMe();

undefined となり隠蔽化できたことを確認。

正常に呼び出せます

Page 85: [A 3]SSJSでも使える!Javascriptでオブジェクト指向プログラミング入門

なんだか大分クラスっぽくなりました。

Page 86: [A 3]SSJSでも使える!Javascriptでオブジェクト指向プログラミング入門

ほかにも、クラスっぽい継承もこんなふうに実装出来ます。

var FroutModel = (function() { // private変数var name = “none";

// コンストラクタvar cls = function(pname){name = pname;};

// 親クラスの継承cls.prototype = new BaseModel();

// public メソッドcls.prototype.callMe = function() {alert("This is "+name);};

return cls;} () );

こんな感じ。BaseModel オブジェクトはFroutModel オブジェクトと同様な実装をしているもの

とします。

Page 87: [A 3]SSJSでも使える!Javascriptでオブジェクト指向プログラミング入門

コードの説明は今までの応用である程度説明できます。是非パズル感覚でチャレンジしてみてください。

var FroutModel = (function() { // private変数var name = “none";

// コンストラクタvar cls = function(pname){name = pname;};

// 親クラスの継承cls.prototype = new BaseModel();

// public メソッドcls.prototype.callMe = function() {alert("This is "+name);};

return cls;} () );

(ヒント)スコープチェインのルールによりスコープの外から中は見えない。

(ヒント)FroutModel 関数オブジェクトの中で別関数オブジ

ェクトを生成。

(ヒント) FroutModel 内で生成したオブジェクトを返している。

(ヒント)即時関数である

Page 88: [A 3]SSJSでも使える!Javascriptでオブジェクト指向プログラミング入門

今回、

XPagesの話が1つも出ませんでしたが、

Page 89: [A 3]SSJSでも使える!Javascriptでオブジェクト指向プログラミング入門

今回のJavascriptの内容は

クライアントサイドJavascript

サーバーサイドJavascript

どちらにも通用する概念です。

Page 90: [A 3]SSJSでも使える!Javascriptでオブジェクト指向プログラミング入門

試しに最後のクラスっぽい実装のオブジェクトをSSJSのスクリプトライブラリにコピペしてもそのまま動きます。

var AppModel = (function() { // private変数var name = “none";

// コンストラクタvar cls = function(pname){name = pname;};

// 親クラスの継承cls.prototype = new BaseModel();

// public メソッドcls.prototype.func1 = function() {…};

return cls;} () );

実際に、自分もこのオブジェクトの構成をテンプレートとしてJavascript

でのOOPに利用しています。

Page 91: [A 3]SSJSでも使える!Javascriptでオブジェクト指向プログラミング入門

スクリプトライブラリにコピペ

Page 92: [A 3]SSJSでも使える!Javascriptでオブジェクト指向プログラミング入門

XPagesから呼び出し出力結果

一旦viewScopeにnewしたオブジェクトを

格納しています

Page 93: [A 3]SSJSでも使える!Javascriptでオブジェクト指向プログラミング入門

XPagesでOOPを利用するときの注意点

viewScopeにnewしたオブジェクトを格納しましたが、

オブジェクトを永続的に保持して利用出来るようにするため、Xspプロパティより「ページをメモリに保存する」を選択します。

Page 94: [A 3]SSJSでも使える!Javascriptでオブジェクト指向プログラミング入門

いかがでしたでしょうか?

Javascriptのオブジェクト指向プログラミングは

理解するまで色々と試してみるのが一番だと思います。

なんせHTMLファイル1つで試せます。

<!DOCTYPE html>

<html>

<head>

<script type="text/javascript">

// <![CDATA[

var FroutModel = (function() {

// private variable

var name = "hoge";

// コンストラクタvar cls = function(pname){name = pname;};

// メソッドcls.prototype.callMe = function() {alert("This is "+name);};

return cls;

}());

var frt = new FroutModel("Banana");

frt.callMe();

alert("frout.name="+frt.name);

// ]]>

</script>

</head>

<body>

</body>

</html>

Page 95: [A 3]SSJSでも使える!Javascriptでオブジェクト指向プログラミング入門

気づいたらDojoもjQueryももう怖くない、かも

Page 96: [A 3]SSJSでも使える!Javascriptでオブジェクト指向プログラミング入門

参考 • 最強オブジェクト指向言語 JavaScript 再入門株式会社フォーエンキーのノジマ様のスライド

http://www.slideshare.net/yuka2py/javascript-23768378

• ブログ XPagesで行こう!IBMチャンピオン リコーITソリューションズ株式会社 海老原 賢次さんのブログ

https://www.ibm.com/developerworks/community/blogs/ebi/

• MDN > 開発者向けのWeb技術 > JavascriptMozilla Developer Network 内のJavascript ポータル

https://developer.mozilla.org/ja/docs/Web/JavaScript

• JSLintバッドプラクティスに対して警告を出す構文チェッカー

http://www.jslint.com/

Page 97: [A 3]SSJSでも使える!Javascriptでオブジェクト指向プログラミング入門

ご清聴ありがとうございました

Page 98: [A 3]SSJSでも使える!Javascriptでオブジェクト指向プログラミング入門

www.ktrick.com

この 文書 は クリエイティブ・コモンズ 表示 - 継承 2.1 日本 ライセンスの下に提供されています。