jQuery源碼筆記(二):定義了一些變量和函數 jQuery = function(){}

筆記(二)也分爲三部分:css

1、jquery

介紹:web

註釋說明:v2.0.3版本、Sizzle選擇器、MIT軟件許可
註釋中的#的信息索引、查詢地址(英文版)
匿名函數自執行:window參數及undefined參數意義
'use strict' 嚴格模式:代碼規範及其不推薦嚴格模式理由
rootjQuery根節點:document 獲取及其聲明意義
readyList DOM加載相關……
typeof undefined 字符串形式'undefined'的存放及其意義。數組

 

先看開頭的註釋:瀏覽器

/*!
 * jQuery JavaScript Library v2.0.3
 * http://jquery.com/
 *
 * Includes Sizzle.js
 * http://sizzlejs.com/
 *
 * Copyright 2005, 2013 jQuery Foundation, Inc. and other contributors
 * Released under the MIT license
 * http://jquery.org/license
 *
 * Date: 2013-07-03T13:30Z
 */

這注釋有什麼意思呢:版本-官網-Sizzle-Sizzle網站-jQuery版權-許可證-最新更新時間緩存

jQuery的註釋很是多,並且常常能夠看到這些東西:(#13335),便是括號裏面的#加數字。就是經過它能夠找打更詳細的說明。app

能夠在官網找到BUG TRACKER,進去之後就能夠直接用索引搜索了。不過新版的jQuery已經沒有用這個了。函數

 

匿名函數自執行:工具

(function( window, undefined ) {

})(window)

就是使得變量和函數不與外部變量和函數相沖突。優化

爲何還要傳window參數呢,直接在裏面使用window不就好了嗎?

window在JavaScript中屬於最頂端,根據做用域鏈機制,查找會比較慢。而將window做爲參數,使得 window 由全局變量變爲局部變量,當在 jQuery 代碼塊中訪問window 時,不須要將做用域鏈回退到頂層做用域,這樣能夠更快的訪問 window;這還不是關鍵所在,更重要的是,將 window 做爲參數傳入,能夠在壓縮代碼時進行優化。好比不傳參的話,這時候window在壓縮版本中是壓縮不了的,壓縮了就不知道是什麼意思了。

壓縮版本以下:

(function(e,undefined){

})

undefined:undefined不是保留字,也不是關鍵字,只是window下的一個屬性,在有些瀏覽器中,它是能夠被修改的。因此就經過傳參的形式,以避免被修改。

 

繼續看註釋:

// Can't do this because several apps including ASP.NET trace
// the stack via arguments.caller.callee and Firefox dies if
// you try to trace through "use strict" call chains. (#13335)
// Support: Firefox 18+
//"use strict";

出現嚴格模式的註釋,可是建議咱們不要用。由於它仍是存在不少問題的。不過最新版本已經在使用了。

仍是平時寫代碼規範點就好。

 

變量:rootjQuery:jQuery的根目錄,在[866行]有這麼一句話:rootjQuery = jQuery(document);

    // A central reference to the root jQuery(document)
    rootjQuery,

使用變量仍是考慮到壓縮優化的時候,並且可一提升維護性,由於提供變量更接近語義性,更能知道它的做用。

 

變量readyList:與DOM加載有關,在拓展工具方法和複雜選擇器之間。

    // The deferred used on DOM ready
    readyList,

 

core_strundefined = typeof undefined:保存一個字符串形式的undefined,爲何要這樣使用?以下:

window.a == undefined;

typeof window.a == "undefined";

這兩種方法均可以判斷是否爲undefined,不過有些狀況下window.a == undefined這種方式判斷不了,好比IE9。另外一種方式兼容性比較高

 

2、

介紹:

常見對象存儲:location、document、docElem
變量名防止衝突:$()、jQuery() class2type
判斷數據類型、預留檢測方式
core_deletedIds 舊版本的ID刪除、新版本只作爲數組方法引用
core_version = '2.0.3' 版本號存儲
一些新方法的存儲……如:trim()
jQuery函數:$()、jQuery() 返回對象
原生JS面向對象的寫法示例
jQuery面向對象方式:省去初始化元素和建立對象、直接使用內置方法
對象引用實現共享方法:jQuery.fn.init.prototype = jQuery.fn;

 

對象存儲:

    // Use the correct document accordingly with window argument (sandbox)
    location = window.location,
    document = window.document,
    docElem = document.documentElement,

總之:存儲變量對壓縮頗有意義

 

變量名防止衝突:

    // Map over jQuery in case of overwrite
    _jQuery = window.jQuery,

    // Map over the $ in case of overwrite
    _$ = window.$,

能夠這兩個變量防止衝突:

好比在其餘庫也有可能會用到$這個符號,好比咱們在使用jQuery的時候仍是用了var $ = 10;這個語句,那麼這是jQuery庫裏面就會吧_$=10;若是沒有那個語句,那麼_$在jQuery中就等於undefined。

 

判斷數據類型、預留檢測方式 

    // [[Class]] -> type pairs
    class2type = {},

定義一個對象。在這個方法$.type()會用到的

最終會變成這個形式:class2type = {'[Object String]':'string','[Object Array]':'array'}。作類型判斷,兩個類型,因此是2。

 

core_deletedIds 舊版本的ID刪除、新版本只作爲數組方法引用 :

    // List of deleted data cache ids, so we can reuse them
    core_deletedIds = [],

跟緩存數據有關。這個在2.0中已經沒什麼用處了

 

一些新方法的存儲:

    // Save a reference to some core methods
    core_concat = core_deletedIds.concat,
    core_push = core_deletedIds.push,
    core_slice = core_deletedIds.slice,
    core_indexOf = core_deletedIds.indexOf,
    core_toString = class2type.toString,
    core_hasOwn = class2type.hasOwnProperty,
    core_trim = core_version.trim,

 

jQuery函數:$()、jQuery() 返回對象 :

    jQuery = function( selector, context ) {
        // The jQuery object is actually just the init constructor 'enhanced'
        return new jQuery.fn.init( selector, context, rootjQuery );
    },

提供了一個接口,這樣咱們就能夠用啦,也就是$(),jquery()。返回的是一個對象。

構造函數:jQuery.fn.init( selector, context, rootjQuery )。

在源碼中會有這句:jQuery.fn = jQuery.prototype,就是把jQuery的原型賦給fn。這樣構造函數就是原型下的init().

//平時在寫面向對象的時候以下:
function A(){};
A.prototype.init = function(){}; //初始化方法
A.prototype.css = function(){};

var a1 = new A();
a1.init();  //先初始化
a1.css();

//對jQuery的
function jQuery(){};
jQuery.prototype.init = function(){};
jQuery.prototype.css = function(){};

//但jQuery並非這樣設計的
function jQuery = function(){
    return new jQuery.prototype.init();
}
jQuery.prototype.init = function(){};
jQuery.prototype.css = function(){};

jQuery().css();

//固然這種寫法是有問題的,由於css()這個方法是在jQuery的,不是在構造函數的

//[283行]:jQuery.fn.init.prototype = jQuery.fn;

//結果是這樣的

  function jQuery = function(){
  return new jQuery.prototype.init();
  }
  jQuery.prototype.init = function(){};
  jQuery.prototype.css = function(){};

  jQuery.prototype.init.prototype = jQuery.prototype;  //添加一個對象的引用

  jQuery().css();

這樣就解決了平時繁瑣的工做了。

 

3、

介紹:

core_pnum:正則數字匹配
core_rnotwhite:正則單詞匹配
rquickExpr:正則標籤匹配(防止XSS木馬注入)
rsingleTag:正則匹配空標籤
rmsPrefix:正則匹配IE下轉換ms
rdashAlpha:正則匹配轉換大寫、數字
fcamelCase:轉駝峯迴調函數
completed:DOM觸發成功時回調函數

 

正則數字匹配 :

    // Used for matching numbers
    core_pnum = /[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/.source,

匹配數字。到css方法設置樣式的時候會用到

 

正則單詞匹配:

    // Used for splitting on whitespace
    core_rnotwhite = /\S+/g,

 

正則標籤匹配(防止XSS木馬注入):

    // 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-]*))$/,

匹配標籤,Prioritize #id over <tag> to avoid XSS via location.hash

好比:<p>aaaaa 或 #div

 

正則匹配空標籤:

    // Match a standalone tag
    rsingleTag = /^<(\w+)\s*\/?>(?:<\/\1>|)$/,

匹配一個獨立的空標籤,好比<p></p>,<div></div>

 

正則匹配IE下轉換ms、正則匹配轉換大寫、數字:

    // Matches dashed string for camelizing
    rmsPrefix = /^-ms-/,    //以下
    rdashAlpha = /-([\da-z])/gi,     //找到橫杆加字字母就轉換成大寫的字母
好比jQuery中有些樣式會轉化:好比
margin-left:marginLeft
-webkit-margin-left:webkitMarginLeft
可是IE裏他會首字母就大寫的:
-ms-margin-left:MsMarginLeft

固然,margin-left並不須要家前綴,只是演示一下而已。

 

轉駝峯迴調函數:

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

 

DOM觸發成功時回調函數:

    // The ready event handler and self cleanup method
    completed = function() {
        document.removeEventListener( "DOMContentLoaded", completed, false );
        window.removeEventListener( "load", completed, false );
        jQuery.ready();
    };
相關文章
相關標籤/搜索