経験は何よりも饒舌

10年後に真価を発揮するかもしれないブログ 

jQueryはいかにしてDOMを取得するか(3)

wafuwafu13.hatenadiary.com

いよいよ今回は、以下のHTMLを用意して実際にDOMを取得していく。

<!DOCTYPE html>
<html>
<head>
    <script src="https://code.jquery.com/jquery-3.5.1.js"></script>
</head>
<body>
<h1 id="hello">hello world</h1>
<script>
    console.log($('#hello'))
</script>
</body>
</html>

まずは前回と同じように、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"#hello"であり、contextrootundefinedであった。

よって、selectorはstring型であるため、3146行目の条件式はtrueになる。
https://github.com/wafuwafu13/jquery-3.5.1/blob/master/jquery-3.5.1.js#L3146

if ( typeof selector === "string" )

次の3147行目の条件式は、selector[ 0 ]#であるため、falseである。
https://github.com/wafuwafu13/jquery-3.5.1/blob/master/jquery-3.5.1.js#L3147

if ( selector[ 0 ] === "<" &&
...

続く3155行目で、変数matchに値が代入されている。
https://github.com/wafuwafu13/jquery-3.5.1/blob/master/jquery-3.5.1.js#L3155

match = rquickExpr.exec( selector );

ここで使われているrquickExprは、3131行目で定義されているRegExpである。
https://github.com/wafuwafu13/jquery-3.5.1/blob/master/jquery-3.5.1.js#L3131

rquickExpr = /^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,

そして、RegExp.prototype.exec()を用い、結果として以下のような配列を返し、変数matchに代入されている。

["#hello", undefined, "hello", index: 0, input: "#hello", groups: undefined]

よって、3159行目の条件式はtrueになる。
https://github.com/wafuwafu13/jquery-3.5.1/blob/master/jquery-3.5.1.js#L3159

if ( match && ( match[ 1 ] || !context ) ) {

match[1]undefinedであるため、3162行目の条件式はfalseである。
https://github.com/wafuwafu13/jquery-3.5.1/blob/master/jquery-3.5.1.js#L3162

if ( match[ 1 ] ) {

続く3192行目で、Document.getElementById()によりDOMが取得されている。
https://github.com/wafuwafu13/jquery-3.5.1/blob/master/jquery-3.5.1.js#L3192

elem = document.getElementById( match[ 2 ] );

document.getElementById("hello")の返り値はElementオブジェクトであり、以下のような値である。

h1#hello {align: "", title: "", lang: "", translate: true, dir: "", …},

続く3194行目からは、前回と同じ処理がなされている。
https://github.com/wafuwafu13/jquery-3.5.1/blob/master/jquery-3.5.1.js#L3194

if ( elem ) {

    // Inject the element directly into the jQuery object
    this[ 0 ] = elem;
    this.length = 1;
}
return this;

よって、console.log($('#hello'))で以下の値が得られた。

▽jQuery.fn.init [h1#hello]
 ▷0: h1#hello
    length: 1
 ▷__proto__: Object(0)

今回でjQueryはいかにしてDOMを取得するかが解明できた。
次は違うコードを読んでいきたい。