前の関連記事:Blogger:ページ番号付ページナビ(5)グローバル変数の除去など
オブジェクトインターフェースモジュールパターンでモジュール化
[意訳]初学者のためのJavaScriptモジュール講座 Part1 - Qiita
ここで紹介されている例3のモジュール化手法です。
グローバルスコープにオブジェクトを渡し、その渡したオブジェクト以外はローカルスコープにとどめます。
JavaScriptプロトタイプチェーン(6)プロトタイプの継承パターン(Prototypal Inheritance)で「関数型継承パターンでカプセル化を実現する」と同じ手法ですし、SyntaxHighlighter3.0.83も3.0.9も同じ手法をとっています。
pagenavi.js
(これはフィードを受け取るコールバック関数はグローバル関数でないといけないと勘違いして作成したものです。実際はコールバック関数はモジュールのプロパティの関数で呼び出せばよかったので修正しました。pagenavi.js これが修正したものです。)
グローバルオブジェクトはPageNavi_Bloggerだけです。
PageNavi_Bloggerには無名関数が入っており、その関数のローカルスコープでページナビが必要とする変数をやりとりしています。
つまりグローバルスコープに代わって無名関数の静的スコープとそのスコープの中にある関数のペアがクロージャを形成していることになります。
クロージャの中の変数はpgのみにしてオブジェクトリテラルでそのプロパティに変数や関数を設定しています。
グローバルスコープに出さざるを得ないといけないもの
すでに前回グローバル変数を除去したあとなのでpgに入っているのはグローバルスコープに出さざるを得ないものだけなので、最後にpgをグローバルスコープにreturnしています。
グローバルスコープに出さざるを得ないものは状態によって変更するかもしれない変数、JSONPのコールバック関数、設置するボタンから呼び出す関数、です。
これらをPageNavi_Bloggerのプロパティに設定しました。
コールバック関数はコールバック関数を返す関数から返されます。
ローカルスコープからコールバック関数を返す関数が呼ばれてもその関数がグローバルスコープにあると返された関数もグローバルスコープになっていました。
(その通りなのですが、コールバック関数もPageNavi_Bloggerのプロパティで呼び出せばうまくいきました。)
グローバルコープからアクセスする必要があるものはpgではなくPageNavi_Bloggerのプロパティにアクセスしないといけません。
ボタンから呼び出す関数はグローバルスコープから呼び出すことになる
function paginavi_button(noPage, perPage, postLabel, text) { // redirectするボタンの作成。 //ボタンから起動する関数はグローバルスコープから呼ばれるのでpgではなくPageNavi_Bloggerで呼び出す。 return '<span class="displaypageNum"><a href="#" onclick="PageNavi_Blogger.buttuns.paginavi_redirect(' + noPage + ',' + perPage + ',\'' + postLabel + '\');return false">' + text + '</a></span>'; // postLabelは文字列なので、クオーテーションが必要。undefinedも文字列として解釈される。 }htmlに出力するボタンから呼び出す関数はグローバルから呼び出すことになるのでpgではなくPageNavi_Bloggerのプロパティにアクセスしないといけませんので、pg.buttuns.paginavi_redirect()ではなくPageNavi_Blogger.buttuns.paginavi_redirect()としないといけません。
Blogger:SyntaxHighlighter(1)ブログにソースコードを綺麗に表示させるで初めてSyntaxHighlighter 3.0.83のソースを読んだときは全く仕組みがわからなかったのですが、ようやくわかるようになってきました。
参考にしたサイト
[意訳]初学者のためのJavaScriptモジュール講座 Part1 - Qiita
JavaScriptのモジュール化についてパターン分けされていてわかりやすい解説です。
0 件のコメント:
コメントを投稿