框架的封装(一)

2019-06-30  本文已影响0人  Amy_yqh

一、入口函数

  1. 方法定义的位置---对象上
(function(global){
    function jQuery(selector){
        const elements = document.getElementsByTagName(selector);
        elements.css = function(){
            console.log('css方法')
        }
        return elements;
    }
    global.$ = global.jQuery = jQuery;
})(window)

$('div').css()

(1)把css方法定义在对象上,随着$()操作的频次 增加,会创造无数个css方法,造成内存的浪费。所以这种方法不行。

2.方法定义的位置---原型上

(function(global){
    function jQuery(selector){
        const elements = document.getElementsByTagName(selector);
        return elements;
    }
    HTMLCollection.prototype.css = function(){
        console.log('原型上的css方法')
    }
    global.$ = global.jQuery = jQuery;
})(window)

$('div').css()

既然我们不能把方法定义在对象上,那我们就把方法绑定到对象的原型上。我们在控制台上,获取body对象,获取到他的原型


image.png

但是,如果把方法绑定到原型上,这样就容易造成原来原型结构的破坏。此方法也不合适。

3.方法定义的位置---自定义对象上

(function(global){
    function jQuery(selector){
        const elements = document.getElementsByTagName(selector);
        return new F(elements);
    }
    function F(elements){
        this.elements = elements;
    }
    F.prototype.css = function(name,value){
       for(let i =0;i<this.elements.length;i++){
           let element = this.elements[i];
           element.style[name] = value;
       }
    }
    global.$ = global.jQuery = jQuery;
})(window)

$('div').css('color','red')

新定义一个新的构造函数F,并把css方法绑定到F的原型上,完美解决问题。不过现在还有一点点不足之处,如果我们设置类名或者id的时候就报错,再修改一下,以便获取标签名或者类名获取id都能正常使用

(function(global){
    function jQuery(selector){
        return new F(selector);
    }
    function F(selector){
        const elements = document.querySelectorAll(selector);
        this.elements = elements;
    }
    F.prototype.css = function(name,value){
       for(let i =0;i<this.elements.length;i++){
           let element = this.elements[i];
           element.style[name] = value;
       }
    }
    global.$ = global.jQuery = jQuery;
})(window)

$('div').css('color','red')
$('.span').css('background','red')
$('#spaniD').css('fontSize','20px')

4.方法,构造函数绑定到jQuery.prototype上

(function(global){
    function jQuery(selector){ 
        return new jQuery.fn.init(selector);  //创建出来的是init实例
    }
    jQuery.fn = jQuery.prototype = { //jQuery.fn简化代码
        constructor:jQuery,
        init:function(selector){ 
            const elements = document.querySelectorAll(selector);
                for(let i =0;i<elements.length;i++){
                this[i] = elements[i];        // 为了方便操作,把所有的dom绑定到对象上
            }
            this.length =elements.length;
        },
        css:function(name,value){
            for(let i =0;i<this.length;i++){
                let element = this[i];
                element.style[name] = value;
            }
        }
    }
    // jQuery.prototype.init的prototype指向jQuery的prototyp,是为了能让
//由jQuery.prototype.init创建的实例
    // 能访问到jQuery.prototype 的方法
    jQuery.fn.init.prototype = jQuery.fn; 
    global.$ = global.jQuery = jQuery;
})(window)

$('div').css('color','red')
$('.span').css('background','red')
$('#spaniD').css('fontSize','20px')

注意:
(1)jQuery.prototype.init的prototype指向jQuery的prototyp,是为了能
让由jQuery.prototype.init创建的实例能访问到jQuery.prototype 的方

5.jQuery.extend封装

(function(global){
    function jQuery(selector){ 
        return new jQuery.fn.init(selector);  //创建出来的是init实例
    }
    jQuery.fn = jQuery.prototype = { //jQuery.fn简化代码
        constructor:jQuery,
        init:function(selector){ 
            const elements = document.querySelectorAll(selector);
                for(let i =0;i<elements.length;i++){
                this[i] = elements[i];        // 为了方便操作,把所有的dom绑定到对象上
            }
            this.length =elements.length;
        },
        css:function(name,value){
            for(let i =0;i<this.length;i++){
                let element = this[i];
                element.style[name] = value;
            }
        }
    }
    jQuery.extend = function(...args){
        var target = args[0];
        for(let i =1;i<args.length;i++){
            let arg = args[i];
            for(let key in arg){
                target[key] = arg[key];
            }
        }
        return target;
    }
    jQuery.fn.init.prototype = jQuery.fn; 
    global.$ = global.jQuery = jQuery;
})(window)

var p = {age:2};
$.extend(p,{name:'胖金妹'},{age:1},{gender:'female',name:'骚哆哩'})
console.log(p)

6 jQuery.extend和jQuery.fn.extend的封装

(function(global){
    function jQuery(selector){ 
        return new jQuery.fn.init(selector);  //创建出来的是init实例
    }
    jQuery.fn = jQuery.prototype = { //jQuery.fn简化代码
        constructor:jQuery,
        init:function(selector){ 
            const elements = document.querySelectorAll(selector);
                for(let i =0;i<elements.length;i++){
                this[i] = elements[i];        // 为了方便操作,把所有的dom绑定到对象上
            }
            this.length =elements.length;
        },
        css:function(name,value){
            for(let i =0;i<this.length;i++){
                let element = this[i];
                element.style[name] = value;
            }
        }
    }
    jQuery.fn.extend=jQuery.extend = function(...args){
        let source = [...args];
        let target = null;
        debugger
        if(this===jQuery){
            target = args[0];  // $.extend
            source.splice(0,1)
        }else{
            console.log(jQuery.fn ==this)
            target = this
        }
       // 拷贝方法1:
        // for(let i=0;i<source.length;i++){
        //     let item  = source[i];
        //     for(let key in item){
        //         target[key] = item[key];
        //     }
        // }
        // 拷贝方法2:
        // source.forEach(function(item,index){
        //     // Object.keys 获取item对象所有的key,结果为一个数组
        //     Object.keys(item).forEach(function(key){
        //         target[key] = item[key]
        //     })
        // })
        // 拷贝方法3:
        // source.forEach(function(item,index){
        //     Object.assign(target,item)
        // })
        // 拷贝方法4:
        Object.assign(target,...source)
      
        return target;
    }
    jQuery.fn.init.prototype = jQuery.fn; 
    global.$ = global.jQuery = jQuery;
})(window)

var p = {age:2};
$.extend(p,{name:'胖金妹'},{age:1},{gender:'female',name:'骚哆哩'})
$.fn.extend({
    formatter:function(){
        console.log('格式化')
    },
    dataFormatter:function(){
        console.log('日期格式化')
    }
})

// $.extend() 对象的拷贝
// $.fn.extend() 实现方法对象的拷贝(给jQuery.fn扩展方法)
上一篇 下一篇

猜你喜欢

热点阅读