zoukankan      html  css  js  c++  java
  • jQuery源码笔记(二):定义了一些变量和函数 jQuery = function(){}

    笔记(二)也分为三部分:

    一、

    介绍:

    注释说明: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),即是括号里面的#加数字。就是通过它可以找打更详细的说明。

    可以在官网找到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。另一种方式兼容性比较高

    二、

    介绍:

    常见对象存储: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();

    这样就解决了平时繁琐的工作了。

    三、

    介绍:

    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*(<[wW]+>)[^>]*|#([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();
        };
  • 相关阅读:
    面试准备
    session
    memcached优化方案实例
    MySQL用户管理
    MySQL事务
    Linux防火墙
    Linux权限体系
    Linux查看日志文件
    查看系统状态
    负载均衡(六)分表分库的负载均衡
  • 原文地址:https://www.cnblogs.com/Chen-XiaoJun/p/6219009.html
Copyright © 2011-2022 走看看