Born Neet

- The Emotional Programmer -

Shortcut Key
Next Entry … jPrev Entry … k
Next Page … J(Shift + j)Prev Page … K(Shift + k)
Scroll Down … Space / Page Down
Scroll Up … Shift + Space / Page Up
2008.06.14(Sat.) 09:25
 

ということで早速実践。

っていうかこれ作るために勉強したんだけどね。

遅延学習♪遅延学習♪

でも実用性は不明という。
なんで作ろうと思ったんだっけ?

まぁ、なんだかんだでいろいろと勉強になったし、
どうぜ外部jsを読み込むタイプのbookmarkletには必須の知識だから、いいか!

load_jQuery(with prompt)
load_jQuery(load only)

with promptの方は読み込み後に表示されるプロンプトに実行したいjsのコードを入力するようになってます。
try~catchしてるので、空白とか適当でも大丈夫なはずです。

load onlyの方は、ロード完了後、jQueryのバージョンをalertで表示し(load onlyじゃないじゃん!)て終わりです。
(っていうか何もしないならわざわざ読み込みを待つ必要なかったですね;)

これだけです。
やっぱ特に使い道はなさそう…。

ちなみに、jQueryはAJAX Libraries APIから読み込んでます。
堂々と直リンクできるのはいいですね、googleに感謝!

あ、あとbookmarkletted(?) by bookmarkletterです。
一応宣伝しとく(笑)
意外と使いやすいですよ?

今日は以上です。
短いですが、2日連続長文だったのでちょうどいいかな?

2008.06.13(Fri.) 19:43
 

っぽいタイトルにしてみました。
釣りと言われたら否定できませんm(_ _)m

では、本題。

昨日の記事を書くために改めてクロージャについて調べてみたんですが、
昨年後半からかなりの数の記事が書かれてることに今さら気づきました。

2007~8年はクロージャ入門記事が豊作だったようですね。
何かありましたっけ?
やっぱり、JavaScript 第5版の出版の影響で理解できた人が増えたりしてるんでしょうか。

何はともあれ、僕が悩みまくって「これはひどい」な記事を書いてた頃より、さらに学びやすくなってると思います。
(この時はなぜか今回あげた記事を全て見逃していました…)

ってことで一度断念した人も、

Cでいうならポインタ!
ギターでいうならF!!
(初心者にとって大きな壁になるという意味でね)

なJavaScriptのクロージャに再挑戦してみませんか。

以下ただのまとめです。
(2007年以降の記事に絞ってみました…つもりです、古いのまざってたらごめんなさい)

Core JavaScript 1.5 Guide:Working with Closures - MDC
基本的にこれで十分だと思います。
さすが(唯一といってもいい)まともなJSリファレンスを提供してくれてるMDC。

こんなの読んでもわからない?
そうですか、そうですよね。

ならお次は、@ITなんてどうですか?
第3回 変数の宣言とスコープ - @IT

まだまだあります。
nothing but ordinary - JavaScript はじめてのクロージャ入門
クロージャを利用しながらひとつのプログラムを作っていく感じがステキです。

JavaScriptでのクロージャの使い方
ループで犯すミスをわかりやすく解説。

JavaScript クロージャとレキシカルスコープ - Backstage of theater.js
説明が丁寧です。

さっきから何か小難しいんですけど!!
すいません…。

ならこの辺はどうですか?
短いし読みやすいですよ。

あるSEのつぶやき: JavaScriptのクロージャー
Haida's weblog: クロージャ

なんとなくわかってきた気もするけど…。
やっぱ動きがないとイメージ湧かないですよね。
僕もそうです。

この辺は実行できるサンプルがありますよ。
func09 ≫ JavaScript、クロージャをおさらいしてみる
[ヅラド] [JavaScript]クロージャとイベントのサンプル 3種類 5パターン
Bugle Diary: [javascript]クロージャについて

動画もあります。
Web/JavaScript 講習会 part.7 (this, スコープと環境、クロージャ)

スライドも。
JavaScript勉強会

っていうか文系だからわかんないって!?
奇遇ですね、僕もド文型です。

では、読み物風のこちらをどうぞ。
Life is beautiful: Javascriptの黒魔術=クロージャを宮沢賢治風に説明してみる

クイズもあります。
Life is beautiful: Javascriptクイズ(中級者向け):無名関数と実行効率の話
Life is beautiful: Javascript、クロージャを使ったプライベート関数の隠蔽について

以上、ふざけ半分でまとめてみました。

ここにあげたのはごく一部で、まだまだあります。
軽く検索しただけでも30件以上はありました。

JavaScript クロージャ - Google 検索
Yahoo!検索 - JavaScript クロージャ

で探してみてください。

かなりの数の記事がひしめき合ってますので、フィーリングにあう記事が見つかるかもしれませんよ。

2008.06.12(Thu.) 21:50
 

※ 超長文注意!

動的スクリプトローディング(さんざん既出だと思うけど - IT戦記が、さっぱりわかんなくて凹んだ。
でも、いろいろとJSのエッセンスが詰まってそうな気がしたので、頑張って読んでみた。
で、一応わかったつもりにはなれたので説明してみる。
(駄文だけど僕と同じレベルの人にはもしかしたら役に立つかもしれません)

非常に長いですが、よろしければどうぞ。

では、早速始めます。

[引用]

まずは、全体を引用。
(コピーしにくいように一応行番号を入れてます。使わせてもらうなら、せめて本家を訪問するのが礼儀かと。)

 1: var load = function(src, check, next) {
 2:  check = new Function('return !!(' + check + ')');
 3:  if (!check()) {
 4:    var script = document.createElement('script')
 5:    script.src = src;
 6:    document.body.appendChild(script);
 7:    setTimeout(function() {
 8:      if (!check()) setTimeout(arguments.callee, 100);
 9:      else next();
10:    }, 100);
11:  }
12:  else next();
13: };

はい、さっぱりわかりませんね(>_<)
僕もそうでした(す?)。

ってことでこれから、1行ずつ見ていきまーす。
(全ての行を解説します。bornnnetbornneetは初心者を見捨てません!)

[はじめに]

(一応説明)この「関数は外部jsファイルを読み込んで、ロードが完了するのを待った後、指定の関数を実行する」というものです。
(説明が下手ですいません)

実際に使っている場面を想定したほうが(僕は)わかりやすいので、以下の解説では、jQueryを読み込んだ後、alertでバージョンを表示するという体で話を進めます。

つまり、

load(
  'http://ajax.googleapis.com/ajax/libs/jquery/1.2.6/jquery.min.js', 
  'window.jQuery', 
  function() { alert($.fn.jquery); }
);

という呼び出しをしているってことです。 jQueryはAJAX Libraries APIから読み込んでいます。

[本題]

前置きがかなり長くなりましたが、コードリーディング(1回言ってみたかった!)に入ります。

1, 13行目

 1: var load = function(src, check, next) {
13: };

1(~13)行目では、外部jsのロードを行う無名関数を定義して、loadという変数に代入しています。
引数は3つで、それぞれの意味は

src外部jsのURLやパス
check読み込み完了を判断するために、存在の有無を確認するオブジェクト
next完了後に実行したい関数

となっています。

わかりにくいのは、checkですね^^
この関数では、外部jsの読み込み完了を判断する必要がありますが、JSにはそんな機能はありません。
(っていうか外部ファイルのロード自体もHTMLを利用して実現してるぐらいです)
ただ、多くのjsファイル(ライブラリは特に)読み込まれるとグローバル領域に何かしらのオブジェクトを作ります。
なので、そのオブジェクトの有無をチェックすることで、外部jsのロード完了をしろうというわけです。

jQueryだと、window.jQueryがそのオブジェクトになります。(window.はグローバルを示します)

function load(src, check, next) {
}

と書かないのは、前者の方が汎用性が高いためだと思われます。
if文等ブロック内に書けたりとかするので。
(function文だと関数の中に書けないからこっちの形にしてるんだと思ったけど、今回調べてみたらそんな情報は見当たらなかったので勘違いだったみたい)
あと、コピペして使うことを考えるとfunction式にしてた方が使い勝手がいいとか、単にスマートでカッコいいとかの理由で僕もこの方が好きです。

2行目

 2:  check = new Function('return !!(' + check + ')');

2行目はけっこう重要です。
処理としては、引数のcheckで指定されたオブジェクトがグローバル領域に存在するかどうかをチェックする関数を作成して、checkに代入するということをしています。

まず、!!ですが、これはオブジェクトの有無をbooleanに変換するテクニックです。
また、()で括っているので、引数checkの内容を確実に式として評価することができます。
こうすることで、オブジェクトがあるならtrue、ないならfalseという結果を得られます。

evalを使っても同じことができますが、この方が簡単です。
また、window[check]とかだとメソッドまで確認することができないので、やはりこの方法がいいんでしょう。

そして、Functionコンストラクタで定義された関数のスコープはグローバルになるので、グローバル領域に指定のオブジェクトがあるかどうかを知ることができます。

つまり、今回の例だと、

function() {
	return !!(window.jQuery);
}

という関数をグローバルに作ったイメージです。

さらに、この関数はここで実行されるわけではなく、checkという変数に代入されるので、setTimeoutに渡す無名関数の中でも使うことができるのです。(詳細後述)

3, 12行目

 3:  if (!check()) {
12:  else next();

ここは簡単です!

3行目では、さっき作った関数を呼び出して、既にその外部jsが読み込まれていないかを確認します。
指定のオブジェクトがあった場合は、12行目に飛び、実行したい処理を行なって、このload関数は終了します。

4~6行目

 4:    var script = document.createElement('script')
 5:    script.src = src;
 6:    document.body.appendChild(script);

ここも特に難しくありません。
body要素に新しいscript要素を追加することで、外部jsを読み込みます。

今回の場合、

<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.2.6/jquery.min.js"></script>

という要素が追加されることになります。

いよいよメイン!7~10行目

 7:    setTimeout(function() {
 8:      if (!check()) setTimeout(arguments.callee, 100);
 9:      else next();
10:    }, 100);

ここが一番重要&難しいところだと思います。

まず、7行目と10行目では、setTimeoutを使って、渡した無名関数を100ミリ秒後に実行する、という指定を行っています。

そして肝心なのは、その無名関数です。

8行目前半のif文では、2行目で作った関数を呼び出しています。
先ほども書きましたが、無名関数の中では宣言されていないcheckという変数を使っています。

JavaScriptでは、親関数(エンクロージャ)の中で宣言した変数(レキシカル変数)は、その中で作られた関数(クロージャ)からずっと参照することができます。(親関数の実行が終わってもなくなりません)
そのため、ここでもcheck()とすることで、指定オブジェクトの有無を確認する関数を呼び出すことができるのです。
(クロージャの実用的な使い方ですね!)

順番が前後しますが、9行目は外部jsが読み込まれた場合の処理で、実行したい関数を呼び出しています。
このnextも親関数の中で引数として宣言されているので、ここで使用することができます。

ラストスパート!!

長々と説明してきましたが、8行目後半を説明すればおしまいです。
(あとちょっと耐えてください)

ここはcheck()がfalseなら、つまり、まだ指定オブジェクトが存在しない場合に実行される処理です。
さっきと同じようにsetTimeout関数を使っているので、100ミリ秒後にarguments.calleeという怪しいものを実行しようという意味になります。

arguments.calleeは、実行中の関数自身を参照しています。
ここで注意ですが、実行中の関数自身とは、load関数ではなく7行目でsetTimeoutに渡されている無名関数のことです。

したがって、check()がtrueを返すまで、100ミリ秒毎に指定オブジェクトの有無をチェックするという処理を繰り返すことができるのです。

そして!外部jsファイルの読み込みが完了すれば、先ほど説明した9行目が実行されて、



と、表示された後、無事この関数の役目は終了となります。

[おわりに]

以上、僕はこんな風に考えてます。
JS勉強中の同士のお役に立てれば幸いです。
(理解が足りないところも多々あると思いますが…;)

突っ込みは大歓迎です!
お気づきの点があればコメント等でご指摘お願いしますm(_ _)m

[余談]

こういう処理も遅延って表現していいのかなぁ?
amachangさんの記事では動的ロードとされてるけど…。
まぁ遅延ロードって書いてる人もいる(↓)し、いいか!
なにより、遅延って言葉はハッカーっぽくてステキ!!

[See also]

JavaScriptで遅延ロードをする方法についてのおさらい (Clouder::Blogger)
malaさんの作。(オリジナルの記事はこちら
2005年…3年前かぁ、すごいなぁ。
waitのみの実装のため関数自体が短く、あまりトリッキーな書き方もされていないので、こっちの方が直感的にわかりやすいかもです。
需要があれば解説しますよ?
クオリティはこの程度になりますが(笑)

[参考]

Core JavaScript 1.5 Reference:Functions - MDC
Core JavaScript 1.5 Guide:Working with Closures - MDC

[追記]

誤字を訂正。(2008/06/27 19:05)
まさか自分のドメイン名を間違えるとは^^;

2008.06.11(Wed.) 22:37
 

はてなブックマーク - blog.bornneet.com の注目エントリー

っということで、初めて5ユーザにはてブしてもらえました。

初はてブから4ヶ月以上…長かったです。

ブックマークされたエントリは、初めての時と同じく、
Hello, Flash!:ActionScriptを初めて使ってみたらお絵かきが簡単にできてびっくりした - Born Neet
でした。

やっぱ、Flash(AS)って需要あるんですかねー。

なのに2月以来勉強していないというorz

[追記 2008/06/13 19:03]

初はてブは、IE7.jsの記事だったかもです。
まぁどちらにせよ、そこそこ時間かけたエントリが評価されるってことですかね…?

2008.06.07(Sat.) 18:09
 

もうやんなってきた。

いつのまにかWILLCOM 03っていうカッコいい後継機も発表されてるし…。
それでピンクとか出して売り切ろうとしてたんだな?

こっちはあと約2年使わなきゃいけないのにー。

とまぁ愚痴はこれぐらいにして。
(そもそも実質ただだからって衝動的に買った僕が悪いんだし。)

画像ファイルが開けないのは困るので調べた。

おしえて!HOME'Sくん WS011SHのデータ記憶用メモリが不足しています。

どうやらリセット(再起動)すりゃ解決するらしい、ってことでスタイラス(付属のは激しく使いにくいので、キャンドゥで買ったDS用のペン)でポチってみた。

…あっさり解決。(実は2週間ぐらいこの状態のまま放置してた)
この操作は今後何度もすることになりそうだから覚えておこう。

もう頼むよー。
「フォン」としての使い勝手は最悪に近いんだから、せめて「スマート」な部分はいい感じに使わせてくれー。

以上、結局最後まで愚痴でした。

マニュアルはここ(こうも不具合?が多いとダウンロード必須ですね)

  BackHOME : Next 
  • JavaScript 第5版
  • 恋するプログラム―Rubyでつくる人工無脳
  • JavaScriptクイックリファレンス 第5版―JavaScript1.5対応
  • はじめてのAIプログラミング―C言語で作る人工知能と人工無能
  • 初めてのJavaScript―Ajax&DOM対応
自作スクリプト実験
ブログ内検索
カレンダー
06 2008/07 08
S M T W T F S
1 3 4 5
8 9 10 11 12
13 14 15 16 18 19
20 21 22 23 24 25 26
27 28 29 30 31
最近のコメント
[07/06 ゆーいち]
[07/05 ゆーいち]
[07/04 ゆーいち]
[07/03 DREAM☆彡]
[05/25 のり]
最近のトラックバック
RSS
RSS 0.91
RSS 1.0
RSS 2.0
プロフィール
HN:
t*
運営日数:
?日
記事数:
?件
ブログパーツ
あわせて読みたい
スポンサード リンク

Born Neet wrote all articles. 
Powered by Ninja.blog / TemplateDesign by TMP, modified by t*  

お買い得商品満載「楽市楽座」忍者ブログ