jquery源码学习-2-选择器

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <title>jquery1.0.1</title>
    </head>
    <body>
        <div id="box">div#box</div>
        <script src="./jquery.1.0.2.js"></script>
        <script>
            console.log($('<a>'))
            console.log($('#box'))
            /*
                init
                    0: a
                    length: 1
                    __proto__: Object
                init
                    0: div#box
                    context: document
                    length: 1
                    selector: "#box"
                    __proto__: Object
            */
            console.log($(document))
            /*
                init
                    0: document
                    context: document
                    length: 1
            */
        </script>
    </body>
</html>
(function(root){
    var testExp = /^\s*(<[\w\W]+>)[^>]*$/;
    var rejectExp = /^<(\w+)\s*\/?>(?:<\/\l>|)$/;
    var version = '1.0.1'
    var jQuery = function(selector,context){
        return new jQuery.prototype.init(selector,context)
    }
    jQuery.fn = jQuery.prototype = {
        length:0, //merge中使用。。。???
        jQuery:version,
        selector:'',    //调用时传过来的参数,可以使对象,函数,字符串
        init:function(selector,context){ //context 限定查询的范围
            context = context || document;
            var match,elem,index= 0;
            if(!selector){ //$() | $(undefine) | $(null) | $(fasle)
                return this;
            } 
            if( typeof selector === 'string' ){ //两个用途,1、创建DOM节点,,2、查询DOM节点
                if( selector.charAt(0) ==='<' && selector.charAt(selector.length-1) === '>' && selector.length>=3 ){ //selector是html字符串
                    match = [selector] //存入html字符串
                }
                if( match ){ //创建DOM节点     
                    //合并数组 object(有length属性) [context.createElement(parse[1])](DOM节点)               
                    jQuery.merge(this, jQuery.parseHTML(selector,context));

                }else{  //查询DOM节点
                    elem = document.querySelectorAll(selector); //类数组
                    var elems = Array.prototype.slice.call(elem); //转换成数组
                    this.length = elems.length;
                    for(; index<elems.length; index++){
                        this[index] = elems[index];
                    }
                    this.context = context; //给jquery的实例对象扩展context属性
                    this.selector = selector; ///给jquery的实例对象扩展selector属性
                }
            }else if( selector.nodeType ){ //有nodeType,则传过来的是个对象 this|document|window
                this.context = this[0] = selector;
                this.length = 1;
                return this;
            }else if( typeof selector  == 'function'){ //函数
                //???
            }
        },
    }

    jQuery.fn.init.prototype = jQuery.fn;
    //浅拷贝,深拷贝(第一个参数为true)
    jQuery.fn.extend = jQuery.extend = function(){ //根据参数内容和个数来实现
        var target = arguments[0] || {}
        var length = arguments.length;
        var i = 1;
        var deep = false;
        var option,name,copy,src,copyIsArray,clone;
        if( typeof target === 'boolean'){ //判断是否有深浅拷贝的标识,如果是boolean类型
            deep = target ; //deel复制标识
            target = arguments[1];  //将要拷贝的对象赋值为第二个参数
            i = 2;  //要遍历的参数从第二个开始
        }
        if( typeof target !== 'object'){ //第一个参数不是对象,就给他赋值为空对象
            target = {}
        }
        if(length === i){ //判断参数个数 ,如果参数个数为1,则是为 jquey/jquery实例对象 扩展对象,           
            target = this; //this只想对象的引用
            i--
        }
        //浅拷贝
        for(; i<length; i++){ //如果参数个数不为1,直接从第二个参数开始,若为0,则从第一个开始,产生无用消耗
            if( (option = arguments[i]) != null){
                for(name in option){
                    copy = option[name]
                    src = target[name];
                    if(deep && (jQuery.isPlainObject(copy) || (copyIsArray = jQuery.isArray(copy)))){   //深拷贝
                        if(copyIsArray){
                            copyIsArray = false;
                            clone = src && jQuery.isArray(src)? src :[];
                        }else{                            
                            clone = src && jQuery.isPlainObject(src)? src :{};
                        }
                        target[name] = jQuery.extend(deep,clone,copy)
                    }else if(copy != undefined){ //浅拷贝
                        target[name] = copy;
                    }
                }
            }
        }
        return target
    }
    jQuery.extend({
        isPlainObject:function(obj){
            return toString.call(obj) === '[object Object]'
        },
        isArray:function(obj){
            return toString.call(obj) === '[object Aarray]'
        },        
        /** 
         * @param {*} first     -- jquery的实例对象 => this
         * @param {*} second    -- 数组的引用 => [dom]
         */
        merge:function(first, second){ //合并数组 
            var l = second.length,  //1
                i = first.length,   //0
                j = 0;
            if( typeof l == 'number'){
                for(; j <l; j++){ //给first添加数组,dom节点的创建存储
                    first[i++] = second[j] //0:'a'
                    console.log(first);
                }
            }else{

            }
            first.length = i;
            return first;
        },
        parseHTML:function(data, context ){ //解析html元素
            if(!data ||typeof data != 'string'){
                return null;
            }
            //过滤掉 '<a>' => 'a'
            var parse = rejectExp.exec(data); //用正则提取标签名 
            return [context.createElement(parse[1])]; //创建DOM元素,将元素存入到数组中,将数组返回去
        }
    })
    root.$ = root.jQuery = jQuery
})(this)

猜你喜欢

转载自www.cnblogs.com/slightFly/p/11462266.html