jQueryを読み解く2(40〜90行目)

前回 は、コードリーディング速攻でやめてしまったので
今回はもう少し読んでみます。

変数定義

40〜62行目

よくわかりませんが、Array、Hashのmethodを切り出しています。Firefoxの対応のようです。

// Support: Firefox 18+
// Can't be in strict mode, several libs including ASP.NET trace
// the stack via arguments.caller.callee and Firefox dies if
// you try to trace through "use strict" call chains. (#13335)
//

var arr = [];
var slice = arr.slice;
var concat = arr.concat;
var push = arr.push;
var indexOf = arr.indexOf;

var class2type = {};
var toString = class2type.toString;
var hasOwn = class2type.hasOwnProperty;
var support = {};

66行目〜

ここを見て、jQueryの引数って、selectorとcontextがあったことを思い出しました。
contextほとんど使っていないです。
ここでは、jQuery.fn.init を呼んでいるだけです。後述します。

var
(略)
    // Define a local copy of jQuery
    jQuery = function( 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.fn.init( selector, context );
    },

79行目〜

BOMを削除しているようです。何箇所かで使われています。

   // Support: Android<4.1
    // Make sure we trim BOM and NBSP
    rtrim = /^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,

83行目〜

camelCaseというメソッドで置換のために使用しています。
なかなか便利そうなメソッドです。知りませんでした。
また、replace()ってcallbackを引数に取れるんですね、正規表現にマッチした単位で
callback関数を実行するという実装になっています。
なるほど〜。

   // Matches dashed string for camelizing
    rmsPrefix = /^-ms-/,
    rdashAlpha = /-([\da-z])/gi,

    // Used by jQuery.camelCase as callback to replace()
    fcamelCase = function( all, letter ) {
        return letter.toUpperCase();
    };

// 336行目
    camelCase: function( string ) {
        return string.replace( rmsPrefix, "ms-" ).replace( rdashAlpha, fcamelCase );
    },

init

2728行目〜

ちょっと飛びますが、init を少し見てみます。

var rootjQuery,

    // A simple way to check for HTML strings
    // Prioritize #id over <tag> to avoid XSS via location.hash (#9521)
    // Strict HTML recognition (#11290: must start with <)
    rquickExpr = /^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/,

    init = jQuery.fn.init = function( selector, context ) {

// 2801行目
            // HANDLE: $(expr, $(...))
            } else if ( !context || context.jquery ) {
                return ( context || rootjQuery ).find( selector );

            // HANDLE: $(expr, context)
            // (which is just equivalent to: $(context).find(expr)
            } else {
                return this.constructor( context ).find( selector );

// 2834行目
// Give the init function the jQuery prototype for later instantiation
init.prototype = jQuery.fn;

// Initialize central reference
rootjQuery = jQuery( document );

2801行目以降のところが、selector, context を指定した場合の処理になります。
結局、 contex を指定した場合は、 $('contect').find(selector) という結果が返るようになっています。
context未指定、もしくは、jQuery objectの場合は上のreturnを通ります。
contextを指定した場合(jQuery objectでない)場合は、一旦下のreturnを通りますが、
そのあとjQueryオブジェクト化されたcontextで実行されるため、上のreturnを通るようになります。
 
全然関係ないですが、jQuery objectかどうかってpropertyの jquery で判別してるんですね。なるほどー。

参考

jQueryを読み解く1(〜38行目) - rochefort's blog