console.log
で$('.b').length
の値が返ってくる事を期待しているようですが、
そもそも2つの意味で期待する動作はされません。
- jQueryのbindやscrollの引数に渡した関数は即実行されるわけではない
- 関数スコープの制約で、関数内で宣言した
Sum
変数は外から見えない
2は調べれば一瞬で理解出来ると思うので、1に関して軽く解説します。
javaScriptはシングルスレッドなので、特定の動作を行っている間は次の行を動作させることは出来ません。
なので、シングルスレッド本来の考え方であればの話ですが、
$("#a").bind('keyup', fn)
でキーが上がるまでずーっと待ちぼうける作りになるはずで、一生次の行が動くことはありません。
じゃあ1個しかイベントハンドラ指定出来ないじゃんどうすんの!
JavaScriptはイベント駆動で動作します。
コードの動作どおりではなく、内部的には定期的に一瞬だけ「発火されたイベントはあるかな?(チラ見」という事を繰り返しています。
もし発火されたイベントが存在する場合、設定された関数の実行を割り込ませる事で、沢山あるイベントを次々と差し込む事が実現するわけです。
要するに「イベントが発火されたら、引数に渡した関数実行しといてね。じゃあ俺は下の行を実行するからよろしく。」というわけです。
従って、質問文の挙動は下記のようになります。
JavaScript
1$(function(){
2 $("#a").bind('keyup', fn); // イベントハンドラに設定し次の行を実行
3 $(window).scroll(fn); // イベントハンドラに設定し次の行を実行
4 var S = (Sum); // 上記2行の処理はまだ行われていないのでSumの値が変わる事はない
5 console.log(S); // undefinedがコンソールに表示される
6});