読者です 読者をやめる 読者になる 読者になる

jQueryがわからないので真似して書いてみる

第1回 jQueryライブラリ(1~171行目):jquery.jsを読み解く|gihyo.jp … 技術評論社を見ながら勉強。

0017: var jQuery = window.jQuery = function( selector, context ) {
0018: // The jQuery object is actually just the init constructor 'enhanced'
0019: return new jQuery.prototype.init( selector, context );
0020: };
0021:
0522: // Give the init function the jQuery prototype for later instantiation
0523: jQuery.prototype.init.prototype = jQuery.prototype;

17行目がまさにjQueryの根幹となる部分で,ここでjQueryオブジェクトを定義しています。jQueryオブジェクトの実体はinitメソッドによるコンストラクタで,オブジェクトが生成された際にinit()メソッドを実行してインスタンスを返します。よって,jquery.jsのロード時には定義が行われるのみで,jQuery関数(もしくは$)が呼ばれて初めて jQueryのプロトタイプオブジェクトのinit()が実行され,処理が行われます。

ここが良くわからなくて、どんな動きになるか自分で書いてみた。

  1. jQueryの代わりにaというオブジェクトを作ってみる
  2. (function(...){})()で囲っても後で呼べるようにaをwindowのプロパティにする
  3. 以下の3つのメソッドを用意
    • init:プロパティをセット
    • add:上でセットしたプロパティに文字列を付け足し。その出力。メソッドチェーン(?)のためにthis.show()を返す
    • show:プロパティの表示。メソッドチェーン(?)のためにthisを返す

で、コードを書いてみた。

(function(){
    var a = window.a = function(args) {
        return new a.prototype.init(args);
    }
    a.prototype = {
      init: function(args) {
          this.property = 'property: ' + args;
      },
      add: function(args) {
          this.property += args;
          return this.show();  // 中からもthisでメソッド使えることの確認
      },
      show: function() {
          alert(this.property);
          return this;
      }
    }

    a.prototype.init.prototype = a.prototype; // init の new 時に a.prototypeを設定する http://nanto.asablo.jp/blog/2005/10/24/118564
})()

気になってる点は

  • a()を実行した時に実行されるnew a.prototype.init()の意味
  • a.prototype.init.prototype = a.prototypeがある場合とない場合は何が違うか

この状態で、色々試してみる。

実行

まず、

a()を実行した時に実行されるnew a.prototype.init()の意味
a.prototype.init.prototype = a.prototypeがある場合とない場合は何が違うか

だけど、JavaScript の new 演算子の意味: Days on the Moonにあるのを参考にすると、newがやることは

1. 新しいオブジェクトを作る。
2. 1 で作ったオブジェクトの Prototype 内部プロパティ (__proto__ プロパティ) に F.prototype の値を設定する。

らしいので「a.prototype.init.prototype = a.prototype」がないと、newをやってもinit.prototypeがないわけだけから、
そもそもadd()やshow()が実行できないと。

var b = a('プロパティ')
b.show();

上の例は「a.prototype.init.prototype = a.prototype」があれば「property: プロパティ」が出力されて、
なければエラーになる。
これが、

var b = a.prototype
b.show();

であれば、「a.prototype.init.prototype = a.prototype」がなくてもエラーにはならない。

…ってところでやっぱりわからなくなった。

何でそもそもnewして返してるんだろ?

a('プロパティ1').show().add('付けたし').add('付けたし')  // 

みたいに書けるからかな?
とりあえずまたわかったら書いてみる。