Submit Search
defjs をひも解く
•
1 like
•
1,217 views
Masafumi Oyamada
Follow
1 of 25
Download now
Downloaded 10 times
More Related Content
defjs をひも解く
1.
def.js をひも解く ~オレ標準 js
記法~ id:mooz @stillpedant
2.
自己紹介 • 名前 –
mooz (Hatena, GitHub, …) – stillpedant (Twitter, Google) • 好きな言語 – Mozilla 系 JavaScript • 作ったもの 近影 – KeySnail (Emacs 版 Vimperator) – MiSPLi (Lisp 処理系 in JavaScript) – その他もろもろ 詳しくは http://mooz.github.com/index-ja.html で
3.
def.js
4.
def.js • http://github.com/tobeytailor/def.js • Ruby
に似た記法でクラス定義と継承が行える
5.
サンプルコード
6.
サンプルコード
!?
7.
説明 • def (クラス名)
(定義); – クラス定義 – def ("Person") ({ … }); • def (クラス名) << 親クラス(定義); – 親クラスを指定したクラス定義 (継承) – def (“Ninja") << Person({ … }); • this._super(); – メソッド中から用いる – 親クラスの同名メソッドを呼び出し
8.
サンプルコード (再掲)
9.
今回のスライドの目的 • def.js の挙動を理解する •
def (クラス名) (定義); • def (クラス名) << 親クラス(定義); • this._super();
10.
def (クラス名) (定義);
11.
def (クラス名) (定義); •
def 関数は関数 (deferred) を返す • def(“Person”) とすると – Person クラスが作成され (window.Person が 定義される) – 「定義 (props) を使って Person クラスを拡 張する関数」が返る • つまり def(“Person”)({ … }); とすると – Person クラスが定義され, { … } を使ってその クラスが拡張される ※ “拡張” : メソッドやプロパティを定義すること
12.
def (クラス名) <<
親クラス(定義);
13.
def (クラス名) <<
親クラス(定義); • 前述の通り def 関数は関数 deferred を返す • この関数には valueOf というプロパティが設定 されている • この valueOf がミソ
14.
valueOf • オブジェクトをプリミティブ値に変換する際に
呼ばれる • プリミティブ値が期待される場面にオブジェク トが出くわしたとき自動的に呼ばれる
15.
valueOf の挙動 実行すると, 1.
def(foo) called 2. def(bar) called 3. foo (valueOf) 4. bar (valueOf)
16.
def (クラス名) <<
親クラス(定義); • def 関数は valueOf の設定された関数 deferred を返す • def (クラス名) << 親クラス(定義); とすると合 計で 3 回関数が呼ばれる def (クラス名) 親クラス(定義) dererred.valueOf (def の返り値)
17.
def(“Ninja”) << Person({
… }); def(“Ninja”) << Person({ … }); としたとき…… def(“Ninja”) 1. Ninja クラスを作成 2. deferred.valueOf を設定 3. deferred を返す def.js のコンテキスト内でグローバル _super, _props を設定 deferred Person({ … }); def(“Ninja”) の返した deferred に valueOf が 設定されているので…… 1. deferred の _super に Person を設定 2. deferred の _props に { … } を設定 deferred.valueOf 1. deferred の _props を使い Ninja クラスを拡張 2. deferred の _super を使い Ninja の親クラスを Person に設定 (Ninja に _superClass プロパティを設定する)
18.
つまりは…… • A() 演算子
B() のとき 1. A() 2. B() 3. A の返したオブジェクトの valueOf • という順番で呼ばれてくれれば何でも良い • << である必要性は無い – def(“Ninja”) >> Person({ … }); – def(“Ninja”) + Person({ … });
19.
this._super();
20.
_super(); • 関数の caller
プロパティを使って _super の呼び出し元 メソッドを取得. • メソッドの _class プロパティによりクラスを取得 • クラスの _super プロパティにより親クラスを取得 • メソッドの _name プロパティによりメソッドの名前を 取得し, 親クラスの持つ同名メソッドを呼ぶ
21.
_super() の使う各プロパティ • Klass.extend
時に追加 – メソッドの _name – メソッドの _class • deferred.valueOf により追加 – クラスの _super • JavaScript 標準 – arguments.callee • その関数自身 • JavaScript 非標準 (ほぼ全てのブラウザが実装) – caller プロパティ • その関数を呼んだ関数
22.
まとめ
23.
まとめ • def (クラス名)
(定義); – 関数を返す関数 • def (クラス名) << 親クラス(定義); – valueOf – << である必要なし • this._super(); – arguments.callee.caller
24.
演算子オーバーロード欲しい
25.
資料 • def.js
– http://github.com/tobeytailor/def.js • 日本語の解説コメントをつけたコード – https://gist.github.com/2ac889f4b0276ddf9586 ご静聴ありがとうございました
Download