zoukankan      html  css  js  c++  java
  • jQuery源代码学习笔记:构造jQuery对象

    2.1源代码结构:

    (function( window, undefined ) {
       
        var jQuery = (function() {
           // 构建jQuery对象
           var jQuery = function( selector, context ) {
               return new jQuery.fn.init( selector, context, rootjQuery );
           }
       
           // jQuery对象原型
           jQuery.fn = jQuery.prototype = {
               constructor: jQuery,
               init: function( selector, context, rootjQuery ) {
                  // selector有下面7种分支情况:
                  // DOM元素
                  // body(优化)
                  // 字符串:HTML标签、HTML字符串、#id、选择器表达式
                  // 函数(作为ready回调函数)
                  // 最后返回伪数组
               }
           };
       
           // Give the init function the jQuery prototype for later instantiation
           jQuery.fn.init.prototype = jQuery.fn;
       
           // 合并内容到第一个參数中,兴许大部分功能都通过该函数扩展
           // 通过jQuery.fn.extend扩展的函数,大部分都会调用通过jQuery.extend扩展的同名函数
           jQuery.extend = jQuery.fn.extend = function() {};
          
           // 在jQuery上扩展静态方法
           jQuery.extend({
               // ready bindReady
               // isPlainObject isEmptyObject
               // parseJSON parseXML
               // globalEval
               // each makeArray inArray merge grep map
               // proxy
               // access
               // uaMatch
               // sub
               // browser
           });
     
            // 到这里,jQuery对象构造完毕。后边的代码都是对jQuery或jQuery对象的扩展
           return jQuery;
       
        })();
       
        window.jQuery = window.$ = jQuery;
    })(window);

    1、jQuery()返回的jQuery对象实际上是构造函数jQuery.fn.init()的实例,可是为什么能在构造函数jQuery.fn.init()的实例上调用构造函数jQuery()的原型方法和属性?如$("#id").length和$("#id").size()

    jQuery.fn.init.prototype = jQuery.fn,用构造函数的原型对象覆盖了jQuery.fn.init()的原型对象

    2、为什么要覆盖构造函数jQuery()的原型对象jQuery.prototype?

    在jQury.prototype上定义的属性和方法会被全部jQuery对象继承,这样能够有效降低每一个jQuery对象所需的内存。

    学以致用:

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    
    <html xmlns="http://www.w3.org/1999/xhtml">
    <head>
        <title></title>
        <script type="text/javascript">
            !(function (window, undefined) {
                var  
                rootjQuery,
                jQuery = (function () {
                    var jQuery = function (selector, context, rootjQuery) {
                        return new jQuery.fn.init(selector, context);
                    };
                    jQuery.fn = jQuery.prototype = {
                        constructor: jQuery,
                        init: function (selector, context, rootjQuery) {
                            //alert("test")
                        },
                        length: 0,
                        size: function(){
                            return this.length;
                        }
                    };
                    jQuery.fn.init.prototype = jQuery.fn;
                    return jQuery;
                })();
    
                window.jQuery = window.$ = jQuery;
            })(window);
    
        </script>
        <script type="text/javascript">
            alert($("").size());
        </script>
    </head>
    <body>
    
    </body>
    </html>
    



    2.2 jQuery.extend = jQuery.fn.extend

    // 合并两个或很多其它对象的属性到第一个对象中,jQuery兴许的大部分功能都通过该函数扩展
    // 通过jQuery.fn.extend扩展的函数,大部分都会调用通过jQuery.extend扩展的同名函数
     
    // 假设传入两个或多个对象。全部对象的属性会被加入到第一个对象target
     
    // 假设仅仅传入一个对象,则将对象的属性加入到jQuery对象中。
    // 用这样的方式,我们能够为jQuery命名空间添加新的方法。

    能够用于编写jQuery插件。 // 假设不想改变传入的对象,能够传入一个空对象:$.extend({}, object1, object2); // 默认合并操作是不迭代的。即便target的某个属性是对象或属性。也会被全然覆盖而不是合并 // 第一个參数是true,则会迭代合并 // 从object原型继承的属性会被拷贝 // undefined值不会被拷贝 // 由于性能原因,JavaScript自带类型的属性不会合并 // jQuery.extend( target, [ object1 ], [ objectN ] ) // jQuery.extend( [ deep ], target, object1, [ objectN ] ) jQuery.extend = jQuery.fn.extend = function() { var options, name, src, copy, copyIsArray, clone, target = arguments[0] || {}, i = 1, length = arguments.length, deep = false; // Handle a deep copy situation // 假设第一个參数是boolean型,可能是深度拷贝 if ( typeof target === "boolean" ) { deep = target; target = arguments[1] || {}; // skip the boolean and the target // 跳过boolean和target,从第3个開始 i = 2; } // Handle case when target is a string or something (possible in deep copy) // target不是对象也不是函数。则强制设置为空对象 if ( typeof target !== "object" && !jQuery.isFunction(target) ) { target = {}; } // extend jQuery itself if only one argument is passed // 假设仅仅传入一个參数。则觉得是对jQuery扩展 if ( length === i ) { target = this; --i; } for ( ; i < length; i++ ) { // Only deal with non-null/undefined values // 仅仅处理非空參数 if ( (options = arguments[ i ]) != null ) { // Extend the base object for ( name in options ) { src = target[ name ]; copy = options[ name ]; // Prevent never-ending loop // 避免循环引用 if ( target === copy ) { continue; } // Recurse if we're merging plain objects or arrays // 深度拷贝且值是纯对象或数组,则递归 if ( deep && copy && ( jQuery.isPlainObject(copy) || (copyIsArray = jQuery.isArray(copy)) ) ) { // 假设copy是数组 if ( copyIsArray ) { copyIsArray = false; // clone为src的修正值 clone = src && jQuery.isArray(src) ? src : []; // 假设copy的是对象 } else { // clone为src的修正值 clone = src && jQuery.isPlainObject(src) ? src : {}; } // Never move original objects, clone them // 递归调用jQuery.extend target[ name ] = jQuery.extend( deep, clone, copy ); // Don't bring in undefined values // 不能拷贝空值 } else if ( copy !== undefined ) { target[ name ] = copy; } } } } // Return the modified object // 返回更改后的对象 return target; };





  • 相关阅读:
    hdu1238 Substrings
    CCF试题:高速公路(Targin)
    hdu 1269 迷宫城堡(Targin算法)
    hdu 1253 胜利大逃亡
    NYOJ 55 懒省事的小明
    HDU 1024 Max Sum Plus Plus
    HDU 1087 Super Jumping! Jumping! Jumping!
    HDU 1257 最少拦截系统
    HDU 1069 Monkey and Banana
    HDU 1104 Remainder
  • 原文地址:https://www.cnblogs.com/lcchuguo/p/5336689.html
Copyright © 2011-2022 走看看