• jQuery基本框架解析


    我们研究一下jQuery的源码

    编码方法很简单。 下面是全部代码的开头和结尾。

    (function( window, undefined ) {
     
    var document = window.document,
        navigator = window.navigator,
        location = window.location;
     
        [...] // The main sources are here
         
    window.jQuery = window.$ = jQuery;
    })(window);
    

      

    核心

     下面是主要代码的缩减版,可以看到很多块代码。

    var jQuery = (
          function () {   
    var jQuery = function ( selector, context ) { return new jQuery.fn.init( selector, context, rootjQuery );};     // Map over jQuery in case of overwrite    _jQuery = window.jQuery,     // Map over the $ in case of overwrite    _$ = window.$,    // A central reference to the root jQuery(document)    rootjQuery,    [...]       rootjQuery = jQuery(document);    [...]    return jQuery; })();

    上面代码中jQuery对象的构造函数, jQuery、$和 rootjQuery(一个指向文档的jQuery对象)。

    下面代码解释为什么我们可以用"."和"[]"操作变量jQuery对象。

    trim = String.prototype.trim,
    indexOf = Array.prototype.indexOf,

     对象的构造

    这里是jQuery函数的最神圣的地方。jQuery的prototype的魔力隐藏在这里。

    var 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” 对象并返回。 参看下面代码:

    jQuery.fn = jQuery.prototype = {
        constructor: jQuery,
        init: function( selector, context, rootjQuery ) {
            [...]
        }
        [...]
    }
     
    // Give the init function the jQuery prototype for later instantiation
    jQuery.fn.init.prototype = jQuery.fn;
    至此, 我们可以知道jQuery.fn等同于jQuery prototype,同时,jQuery.fn.init.prototype指向jQuery prototype,  jQuery.fn.init.prototype constructor指向jQuery。这些信息给了我们一个有意思的结论:输入以下代码
    $(document) instanceof jQuery; // true
    $(document) instanceof jQuery.fn.init; // true

    为了帮助理解,请再看下面的例子:

    var Init = function () {
        console.log('[Init]');
    };
     
    var jQuery = function () {
        console.log('[jQuery]');
        return new Init();
    };
     
    Init.prototype = jQuery.prototype = {
        constructor: jQuery
    };
     
    var $elem = jQuery(); // [jQuery] , [Init]
     
    console.log( $elem instanceof jQuery ); // true
    console.log( $elem instanceof Init   ); // true

    可以看出,所有的结构都在一个jQuery.fn.init对象函数里,而jQuery是生产所有jQuery.fn.init对象的工厂。

     解析参数

    有很多种应用jQuery函数的方法:

    $(function () { alert('READY!') }); // Function to be executed only when loading a DOM
    $(document.getElementById('test')); // link on the element
    $('<div />'); // create new element
    $('<div />', { title: 'test' }); // create new element with attributes
     
    // Supports all imaginable and unimaginable css-selectors:
    $('#element'); // element with ip "element"
    $('.element', $previous ); // Find all elements with a class element in $ previous
    $("div[name=city]:visible:has(p)");

    让我们进一步分析jQuery.fn.init函数。

    init: function( selector, context, rootjQuery ) {
        if ( !selector ) return this;
     
        // Handle $(DOMElement)
        if ( selector.nodeType ) return this = selector;
     
        // The body element only exists once, optimize finding it
        if ( selector === "body" && !context ) return this = document.body;
     
        if ( jQuery.isFunction( selector ) ) {
            return rootjQuery.ready( selector );
        }
     
        // Handle HTML strings
        if ( typeof selector === "string" ) {
            // Verify a match, and that no context was specified for #id
            if ( selector.match(quickExpr) ) {
                if ( match[1] ) {
                    return createNewDomElement( match[1] );
                } else {
                    return getById( match[2] )
                }
            } else {
                return jQuery( context ).find( selector );
            }
        }
    },

    前面四小块代码很简单——当参数分别为空、DOM元素、“body”字符串时如何处理。

    Plug-ins Development  创建插件

    很多专业人士都知道js的类可以很简单地通过prototypes进行扩展。

    var MyClass = function () {
        // constructor
    };
     
    MyClass.prototype = {
        // prototype
    };
     
    var instance = new MyClass();
     
    // We can extend the class prototype and new features will be added to all entities, even those whichvare already created
     
    MyClass.prototype.plugin = function () {
        console.log("He's alive!");
    };
     
    instance.plugin(); // He's alive!

    我们可以用同样方法对标准JQuery进行扩展。

    jQuery.prototype.plugin = function () {
        // Here is my plugin
    };
    但是,我们已知fn等于jQuery.prototype,所以可以简写如下:
    jQuery.fn.plugin = function () {
        // Here is my plugin
        // This here refers to jquery-object, from which the method is called
    };

    因为插件会添加属性到所有已存在的实体和将来要新建的实体,所以如果想针对地对某一对象添加属性,可以用静态属性:

    jQuery.plugin = function () {
        // Here is my plugin
    };

    小插件的最佳模式:

    new function (document, $, undefined) {
         
        var privateMethod = function () {
            // private method, used for plugin
        };
         
        $.fn.myPlugin = function () {
             
        };
         
        // and if you need a method that is not bound to the dom-elements:
        $.myPlugin = function () {
             
        };
         
    }(document, jQuery);

     

  • 相关阅读:
    各进制字符串转换
    小度智能音箱开发
    讯飞魔飞智能麦克风-->直接输出串口
    node express SSL 证书布署
    紫外线消毒灯智能控制系统
    智能家居解决方案
    Git 分支管理
    C语言MQTT库MQTTPacket.c使用,尤其接收
    Vue 数组控制CSS
    AOP_02 通过ContextBoundObject、ContextAttribute 上下文对象实现
  • 原文地址:https://www.cnblogs.com/liubingna/p/2957620.html
Copyright © 2020-2023  润新知