jQuery 封装原理,上图+讲述 通俗易懂

图片

jQuery 封装原理,上图+讲述 通俗易懂_第1张图片


讲解

(function(window,undefind){
    function jQuery(){
        return new jQuery.prototype.init()
    }
    jQuery.prototype={
        constructor:jQuery,
        init:function(){
            console.log("初始化已完成")
        }
    }
    jQuery.prototype.init.prototype=jQuery.prototype
    window.jQuery=window.$=jQuery
})(window)


结合上面的图片和代码,进行讲解。(需要补充原型链的知识,可以查看我以前的文章)


jQuery实质是一个闭包,通过代码可以看出外面用的是匿名函数的写法,把window当作实参传入了进去,这样的写法避免了全局变量的污染,保证安全性,当然也提供了入口函数
(占位,待更新ing)



jQuery核心代码(部分)

/*
 * @Author: Jine 
 * @Date: 2020-06-29 22:03:35 
 * @Last Modified by: Jine
 * @Last Modified time: 2020-06-30 22:27:23
 */

(function(window,undefind){
    function jQuery(selector){
        return new jQuery.prototype.init(selector)
    }
    jQuery.prototype={
        constructor:jQuery,
        /*
	1、传入 '' null undefined  NaN  0 false ,返回空jquery对象
	2、字符串:
        代码片段:会将html片段创建好对应DOM元素,并依次存储到jquery对象中返回
        选择器:会将找到的所有指定找到的元素存储到jquery对象中返回
	3、数组:会将数组中的存储的元素依次存储到jquery对象中返回
	4、除以上类型外:会将传入的数据存储到jquery对象中返回
*/
        init:function(selector){
            //调用自定义jQuery对象中的tirm方法,用来去掉开头结尾的空格
            selector=$.trim(selector)
            // 1、传入 '' null undefined  NaN  0 false ,返回空jquery对象
            if(!selector){
                return this;
            }

            //方法处理
            else if($.isFunction(selector)){
                console.log("方法")
            }
            
            // 2、字符串
            //调用自定义jQuery对象中的isString方法
            else if($.isString(selector)){
                console.log("字符串")

                //判断是否是代码片段 
                if($.isHTML(selector)){
                    //根据代码片段创建所有的元素
                    var temp=document.createElement("div")
                    temp.innerHTML=selector

                    //   --- replace_one    此写法被替代 ---
                    // //将创建好的一级元素添加到jQuery当中
                    // for(var i=0;i
                    //     this[i]=temp.children[i]
                    // }
                    // //给jQuery对象添加length属性
                    // this.length=temp.children.length

                    //以下这种写法可以替代上面 replace_one 注释的内容
                    //使代码优化
                    var array=[]
                    
                    //调用了数组对象中的push方法,再调用apply方法,将push中this改为jquery的this
                    //通俗说:就是遍历temp.children,再放入jquery对象中
                    array.push.apply(this,temp.children)

                    //返回加工好的this(jQuery)
                    // return this;
                 }

                //判断是否是选择器
                 else{
                    //根据传入的选择器找到对应的元素
                    var res=document.querySelectorAll(selector)

                    //将找到的元素添加到jQuery对象上
                    var arr=[]
                    arr.push.apply(this,res)

                    //返回加工好的this(jQuery)
                    // return this;
                 } 
            }
            // 3、数组
            //调用自定义jQuery对象中的isArray方法
            else if($.isArray(selector)){
                console.log("数组")

                // --- replace_two --- 此写法被替换
                // //真数组
                // if(({}).toString.apply(selector)=== "[object Array]"){
                //     console.log("真数组")
                //     var arr=[]
                //     arr.push.apply(this,selector)
                //     return this;
                // }else{
                //     //伪数组
                //     console.log("伪数组")
                //     var arr=[]
                //     //将伪数组转为伪数组jQuery对象
                //     //不支持IE8浏览器以下
                //     arr.push.apply(this,selector)
                //     return this;
                // }

                //以下这种写法可以替代上面 replace_two 注释的内容
                //  使代码优化
                var arr=[]
                //不判断真伪数组,直接转为jquery伪数组对象
                arr.push.apply(this,selector)
                // return this    
                
            }
            // 4、除上述类型以外
            else{
                this[0]=selector
                this.length=1
                // return this
            }
            return this
        }
    }
    //可以通过jQuery或者其对象调用extend在创建方法
    jQuery.extend=jQuery.prototype.extend=function(obj){
        for(var key in obj){
            this[key]=obj[key]
        }
    }

    jQuery.extend({
    //判断是否是字符串
    isString:function(str){
        return typeof str==="string"
    },
    //判断是否是html片段
    isHTML:function(html){
        return html.charAt(0)=="<"&&
        html.charAt(html.length-1)==">"&&
        html.length>=3
    },

    //去除字符串俩边空格
    trim:function(str){
        //如果非字符串便返回原样(调用jQuery中isString方法)
        if(!$.isString(str)){
            return str;
        }
        //判断是否支持JS原生trim方法
        if(str.trim){
            return str.trim()
        }else{
            return str.replace(/^\s+|\s+$/g,"")
        }
    },
    
    //判断是否是object对象
    isObject:function(len){
        return typeof len==="object"
    },

    //判断是否有length属性
    inLength:function(len){
        return "length" in len
    },

    //判断是否是window对象
    isWindow:function(win){
        return win === window
    },

    //判断是否是数组
    isArray:function(arr){
        //判断为object,有length属性,不为window对象,便是数组
        if($.isObject(arr)&&!$.isWindow(arr)&&$.inLength(arr)){
            return true
        }else{
            return false
        }
    },

    //判断是否是函数
    isFunction:function(fun){
        return typeof fun ==="function";
    }
    })

    jQuery.prototype.init.prototype=jQuery.prototype
    window.jQuery=window.$=jQuery
})(window)

你可能感兴趣的:(文章)