zoukankan      html  css  js  c++  java
  • JQuery模拟二------添加extend函数和简单选择器

    在原来的基础上添加extend函数和#id选择器

    //自调函数把window这个全局变量传入
    (function(){
        //把jQuery和$另存一份
        var _jQuery = window.jQuery,_$ = window.$;
        //在上次的代码上添加选择器机制
        var jQuery = window.jQuery = window.$ = function(selector,context){
            return  new jQuery.fn.init(selector,context);
    
        }
        //对 HTML strings or ID strings进行判定
        /*可以把它看作是两个正则表达式串:
        第一个:^[^<]*(<(.|s)+>)[^>]*$
        第二个:^#(w+)$
        /^ 字符串开始
        [^<]* 匹配不包含<号的任意长度字符,长度可以为0
        (<(.|s)+ 匹配任意字符或空白符,长度必须大于等于1
        >)[^>]* 匹配不包含>号的任意字符,长度可以为0
        $ 字符串结束
        | 或
        ^ 字符串开始
        # 匹配符号#
        (w+) 匹配a-zA-z0-9,也就是所有英文字母及数字,长度大于等于1
        $/; 结束*/
        var quickExpr = /^[^<]*(<(.|s)+>)[^>]*$|^#(w+)$/;
        jQuery.fn = jQuery.prototype = {
    
            init:function(selector,context){
                selector=selector||document;
                context=context||document;
            //如果传入的是DOM 节点对象
            if ( selector.nodeType ) {
                this[0] = selector;
                this.length = 1;
                return this;
            }
            //对于选择器是字符串有可能是#id
            if ( typeof selector == "string" ) {
                // Are we dealing with HTML string or an ID?
                var match = quickExpr.exec(selector);
                console.log(match);
                // Verify a match, and that no context was specified for #id
                if ( match && (match[0] || !context)) {
                        var elem = document.getElementById( match[3] );
                        this.length=1;
                        return jQuery(elem);
                    }
                    selector = [];
                }
                //console.log("this is:"+Object.prototype.toString.call(this));
                return this;
            },
            //新增加一个方法用来取得或设置jQuery对象的html内容
            html:function(val){
                //遍历通过回调函数来设置innerHTML为val参数
                return jQuery.each(this,function(val){
                    this.innerHTML=val;
                },val);
            },
            length: 0,
            jquery:"1.0.0",
            author:"BaiQiang",
            size:function(){
                return this.length;
            }
        };
        //简单的遍历函数
        jQuery.each=function(obj,callback,args){
            for(var i=0;i<obj.length;i++){
                callback.call(obj[i],args);
            }
            return obj;
        };
        //需要深入理解一下jQuery的复制函数写法
        jQuery.extend = jQuery.fn.extend = function() {
        ///    <summary>
        ///        用一个或多个其他对象来扩展一个对象,返回被扩展的对象。
        ///        用于简化继承。
        ///        jQuery.extend(settings, options);
        ///        var settings = jQuery.extend({}, defaults, options);
        ///    </summary>
        //target是被扩展的对象,默认是第一个参数(下标为0)或者是一个空对象{}
        var target = arguments[0] || {}, i = 1, length = arguments.length, deep = false, options;
        /*如果传进来的首个参数是一个boolean类型的变量,那就证明要进行深度拷贝。
        而这时传进来的argumens[1]就是要拷贝的对象.如果是这种情况,那就要做一些"矫正"工作, 
        因为这个时候,target变量指向的是一个布尔变量而不是我们要拷贝的对象.*/
        if ( target.constructor == Boolean ) {
            deep = target;
            target = arguments[1] || {};
            //这样的话使得i=2直接跳过前两个参数
            i = 2;
        }
    
        // 如果target不是objet 并且也不是function 就默认设置它为{};
        if ( typeof target != "object" && typeof target != "function" )
            target = {};
    
        //一个参数的就是扩展jQuery对象本身
        if ( length == i ) {
            target = this;
            --i;
        }
    
        for ( ; i < length; i++ )
            //非null的扩展对象才把它扩展到被扩展对象上来.
            if ( (options = arguments[ i ]) != null )
                // Extend the base object
                for ( var name in options ) {
                    //target是被扩展对象 options是扩展对象, 它的方法或属性将会被扩展到target上
                    var src = target[ name ], copy = options[ name ];
    
                    // target和copy如果相等还深拷贝的话就出问题了
                    if ( target === copy )
                        continue;
    
                    // Recurse if we're merging object values
                    //递归src和copy深度拷贝即对每一个属性递归 
                    //要是没有nodeType, 就是非Dom对象引用, 可以对它进行深度拷贝
                    if ( deep && copy && typeof copy == "object" && !copy.nodeType )
                        target[ name ] = jQuery.extend( deep,
                            // Never move original objects, clone them
                            src || ( copy.length != null ? [ ] : { } )
                        , copy );
    
                    // Don't bring in undefined values
                    //如果要加进来的引用不是对象的引用(只要不是undefined ) 那就把引用加进来 
                    //可能是覆盖也可能是新建name这个属性或方法
                    else if ( copy !== undefined )
                        target[ name ] = copy;
    
                }
    
        //返回扩展后的被扩展对象
        return target;
    };
        //使用jQuery的原型覆盖init的原型 这样就自动把jQuery.prototype的方法可以在init里面使用
        jQuery.fn.init.prototype=jQuery.fn;
    })(window);

    再来测试一下,给它添加一个getName()方法 然后我们调用一下它

    <!DOCTYPE html>
    <html>
        <head>
            <meta charset="utf-8">
            <script type="text/javascript" src="jquery.js"></script>
        </head>
        <body>
            <script type="text/javascript">
            jQuery.extend({
            getName: function(){
            return "bq's jQuery"
        }
    });
            console.log(jQuery().jquery);
            console.log(jQuery.getName());
            </script>    
        </body>
    </html>

    结果如下 

    1.0.0
    bq's jQuery

     

  • 相关阅读:
    匿名函数
    内置函数
    基础函数--3
    基础函数(2)
    基础函数(1)
    文件的相关操作
    知识点补充,set集合,深浅copy
    is 和 ==的区别
    Django-form组件中过滤当前用户信息
    Django的常用模块引入整理
  • 原文地址:https://www.cnblogs.com/bq12345/p/3674351.html
Copyright © 2011-2022 走看看