jQueryはいかにしてDOMを取得するか(2)
前回は、以下のHTMLを用意し、
<!DOCTYPE html> <html> <head> <script src="https://code.jquery.com/jquery-3.5.1.js"></script> </head> <body> <script> console.log($); </script> </body> </html>
以下の実行結果を得た。
ƒ ( selector, context ) { // The jQuery object is actually just the init constructor 'enhanced' // Need init if jQuery is called (just allow error to be thrown if not included) return new jQuery…
これは、153行目で定義されている定数であった。
https://github.com/wafuwafu13/jquery-3.5.1/blob/master/jquery-3.5.1.js#L153
今回は、console.log($())
とすることで、関数の実行結果、つまり157行目の、
https://github.com/wafuwafu13/jquery-3.5.1/blob/master/jquery-3.5.1.js#L157
jQuery.fn.init( selector, context )
の実行結果を見ていきたい。
関数は、3133行目に定義されている。
https://github.com/wafuwafu13/jquery-3.5.1/blob/master/jquery-3.5.1.js#L3133
jQuery.fn.init = function( selector, context, root ) {...
ここで、引数であるselector
、context
、root
には何が入っているのかを調べると、
selector
は、
#document {location: Location, implementation: DOMImplementation, URL: "file:///Users/tagawahirotaka/Desktop/index.html",....
であり、context
、root
はundefined
であった。
よって、selector
は、Documentであることがわかる。
selector
が未定義ではなく、string型でもないため、3137行目と3146行目の条件分岐はスルーされる。
https://github.com/wafuwafu13/jquery-3.5.1/blob/master/jquery-3.5.1.js#L3137
https://github.com/wafuwafu13/jquery-3.5.1/blob/master/jquery-3.5.1.js#L3146
if ( !selector ) ... if ( typeof selector === "string" )
続く3214行目には以下のような条件分岐がある。
https://github.com/wafuwafu13/jquery-3.5.1/blob/master/jquery-3.5.1.js#L3214
else if ( selector.nodeType )
selector.nodeType
を調べてみると、値は9
であった。
DocumentはNodeを継承しており、Node.nodeTypeの9
は、DOCUMENT_NODE
を意味している。
この3215行目からの条件分岐内で、以下のような処理がなされる。
https://github.com/wafuwafu13/jquery-3.5.1/blob/master/jquery-3.5.1.js#L3215
this[ 0 ] = selector; this.length = 1; return this;
this
はjQuery.fn.init
のことで、そこにselector
が挿入されている。
しかし、console.log($())
の出力を見てみると、
▽jQuery.fn.init {} ▷__proto__: Object(0)
となっているため、後続の処理で破棄されている。
ちなみに、this
がjQuery.fn.init
である理由は、生成されるインスタンス自身がthis
にセットされるからである。
function foo() { console.log(this) // ▽ foo {} // ▷ __proto__: Object } var bar = new foo()