JQueryのソースコードを読んでJavaScriptを勉強!

最近JavaScriptをさわる機会が多く、もうちょっと勉強しないといけないなと思っています。なので、jQuery(1.7.1)のソースコードを読んでみました。

読んで思ったところをまとめてみたいと思います。勉強したことのまとめです。

jQueryの全体像

(function( window, undefined ){

// Use the correct document accordingly with window argument (sandbox)
var document = window.document,
     navigator = window.navigator,
     location = window.location;

var jQuery = (function() {

  // (省略)
  // jQuery の本体のfunctionを作ってreturnする
})();

// (省略)
// jQueryのいろいろな機能の実装

window.jQuery = window.$ = jQuery;

// (3行分くらい省略)

})( window );

基本骨格はこんなところでしょうか?全体が無名関数になっていて、直後に呼びたすという、JavaScriptのお決まりのパターンになっています。

無名関数に window を渡して、引数windowで受けているので、処理本体中の「window」は引数のwindowになっています。第2引数は、渡されていないので、引数undefinedはundefinedとなります。

意図が完全にはわからなかったので、うまく説明できないですが、このあたりを読んだらなんとなく納得しました。

その後、ローカル変数jQueryに機能を実装していって、最後にjQueryをwindow.jQuery、window.$ に代入して、jQueryを公開しています。このあたりも定石だと思いますが、グローバルの名前空間への影響を最小限にする方法として参考になります。

jQuery.extendによる構造化

jQuery.extend({
  noConflict: function( deep ) {
    //(省略)
  },
  isReady: false,
  //(省略)
});
jQuery.extend({
  Deferred: function( func ) {
  //(省略)
});
jQuery.fn.extend({
  //(省略)
});

ひたすらjQuery.extend、そして、jQuery.fn.extendです。コアとなるjQueryのオブジェクトを作って(jQuery.extendも含まれる)、そこに機能を追加していくという実装になっているようです。

機能のまとまりごとに構造化されているので、私みたいな人でも、9000行あるこのソースコードの必要な箇所だけ読むとかできそうです。

(9000行くらい読めとか言われてしまいそうですが><、それは置いといても必要な箇所だけ読めばいいようにしておくことは大切な事だと思います。)

JavaScriptの論理演算子

RubyPHPと違ってJavaScriptには詳しくないので、基本的なことですがはじめて知りました。JavaScriptはそろそろ、ちゃんと言語の勉強しないといけない感じになってきました。

0 || 1

は1として評価されます。trueではありません。

演算子は、まず左側が評価されて、trueならば左側の値が返ります。falseならば、右側の値が評価されて返されます。

これは、Rubyと一緒ですね^^。ちなみに、PHPは||演算子はbooleanを返します。

PHPのごとく

$foo = $foo ? $foo : 'default値';

とかやらなくても

foo = foo || 'default値';

とかできるので便利です。

ちなみに、Rubyだと、

foo ||= 'default値'

です*1。短いですね。

callとかapplyとか使いこなせる気しない

  toString = Object.prototype.toString,
  hasOwn = Object.prototype.hasOwnProperty,
  push = Array.prototype.push,
  slice = Array.prototype.slice,
  trim = String.prototype.trim,
  indexOf = Array.prototype.indexOf,

//(省略)

jQuery.fn = jQuery.prototype = {

  //(省略)

  toArray: function() {
    return slice.call( this, 0 );
  },
  //(省略)

};

このあたりで、callとかapplyとか使われてます。

とかを読むと、Arrayの機能を使うのにcallとか使うと書いてあって、まさにという感じですね。

このあたりは要勉強です。配列っぽいオブジェクトが作りたくなった時、このあたりのお話を思い出そうと思います。

split + each

jQuery.each( ("blur focus focusin focusout load resize scroll unload click dblclick " +
     "mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave " +
     "change select submit keydown keypress keyup error contextmenu").split(" "), function( i, name ) {

文字列を+で連結して改行してるのが見やすくていいですね。
そして、Rubyの%wが便利だと改めて思いました。

%w(blur focus focusin focusout load resize scroll unload click dblclick
     mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave
     change select submit keydown keypress keyup error contextmenu).each do |name|

というわけで、JavaScriptの記事に見せかけた、Rubyの布教記事でした。

*1:Rubyの場合0や''はtrueなので、式の意味合いは少し異なってきます。