zoukankan      html  css  js  c++  java
  • jQuery插件接口的实现,jquery.extend

    http://www.imooc.com/code/3403

    如果jQuery没有插件接口的设计,那么他就像个光杆司令没有兵,就是没有手下,只有自己一个封闭的城堡。因此jQuery城堡需要设计一个大门 - 插件接口,从而打开大门开始招兵买马。当然jQuery除了获得“开发者社区”的大力支持外,也有很多大公司纷纷对它投出了橄榄枝,这也是它成功的关键。

            基于插件接口设计的好处也是颇多的,其中一个最重要的好处是把扩展的功能从主体框架中剥离出去,降低了框架的复杂度。接口的设计好比电脑上的配件如:CPU、内存、硬盘都是作为独立的模块分离出去了,但是主板提供模块的接口,例如支持串口的硬盘,我只要这个硬盘的接口能插上,甭管是500G还是1000G的容量的硬盘,都能使用。所以在软件设计中插件接口的提供把独立的功能与框架以一种很宽松的方式松耦合。

    从之前的分析中我们可以知道jQuery对象的原理,所以一般来说,jQuery插件的开发分为两种:

      ☑  一种是挂在jQuery命名空间下的全局函数,也可称为静态方法;
    
      ☑  另一种是jQuery对象级别的方法,即挂在jQuery原型下的方法,这样通过选择器获取的jQuery对象实例也能共享该方法。

    分别是$.fn.extend()和$.extend()
    //一个参数:$.extend()和$.fn.extend() 不一样
    $.extend({
            fn1: function(){
                console.log("fn1");
            }
        });
        $.fn1();//fn1,加的实例方法
        $.fn.extend({
            fn2: function(){
                console.log("fn2");
            }
        });
        var div = $("#Odiv");
        div.fn2();//fn2,加的静态方法
    //多个参数:复制,$.extend和$.fn.extend是一样的
    $.extend({name:"ss"},{age:11})
    Object {name: "ss", age: 11}
    $.fn.extend({name:"ss"},{age:11})
    Object {name: "ss", age: 11}

    简单来讲这样实现:

    ajQuery.extend = ajQuery.fn.extend = function() {
            var options, src, copy,
                    target = arguments[0] || {},
                    i = 1,
                    length = arguments.length;
    
            //只有一个参数,就是对jQuery自身的扩展处理
            //extend,fn.extend
            if (i === length) {
                target = this; //调用的上下文对象jQuery/或者实例
                i--;
            }
            for (; i < length; i++) {
                //从i开始取参数,不为空开始遍历
                if ((options = arguments[i]) != null) {
                    for (name in options) {
                        copy = options[name];
                        //覆盖拷贝
                        target[name] = copy;
                    }
                }
            }
            return target;
        }

     浅复制

    var obj1 = {name:{name1:"s1",name2:"s2"},age:12};
        var obj2 = {};
        for(var i in obj1){
            obj2[i] = obj1[i];
        }
        console.log(obj2);//obj1.name === obj2.name

    $.extend(false,{A},{B}):浅复制,批向相同的引用,把B中的对象或者值给A即可,无关递归。

    $.extend(true,{A},{B}):深复制,得到一个新的对象,和原来的对象没有关系。B中的对象要通过递归得到新的对象给A。

    extend jQuery实现:

     var $$ = ajQuery = function(selector) {
            //把原型上的init作为构造器
            return new ajQuery.fn.init( selector );
        }
        ajQuery.fn = ajQuery.prototype = {
            name: 'aaron',
            init: function(selector) {
                this.selector = selector;
                return this;
            },
            constructor: ajQuery
        }
        ajQuery.fn.init.prototype = ajQuery.fn;
        ajQuery.extend = ajQuery.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
            if ( typeof target === "boolean" ) {
                deep = target;
    
                // skip the boolean and the target
                target = arguments[ i ] || {};
                i++;
            }
    
            // Handle case when target is a string or something (possible in deep copy)
            if ( typeof target !== "object" && !jQuery.isFunction(target) ) {
                target = {};
            }
    
            // extend jQuery itself if only one argument is passed
            if ( i === length ) {
                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 ];//bb
    
                        // 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)) ) ) {
                            if ( copyIsArray ) {
                                //数组深复制
                                copyIsArray = false;
                                clone = src && jQuery.isArray(src) ? src : [];
                            } else {
                                //对象深复制
                                clone = src && jQuery.isPlainObject(src) ? src : {};
                            }
                            // Never move original objects, clone them
                            //递归实现深复制
                            target[ name ] = ajQuery.extend( deep, clone, copy );
                            // Don't bring in undefined values
                        } else if ( copy !== undefined ) {
                            //浅复制:指向同样的地址
                            target[ name ] = copy;
                        }
                    }
                }
            }
    
            // Return the modified object
            return target;
        };
        var aa = {a:"aaaa"};
        ajQuery.extend(true,aa,{b:"bb",c:{c1:"c111",c2:"c222"}});
  • 相关阅读:
    假脱机技术
    HTTP报文
    字符串转换成浮点数的方法
    表变量与临时表空间
    规范浮点数
    什么是批处理
    浅谈性能测试、压力测试和负载测试
    关于CSDN的一个安全漏洞
    HttpWatch7.0测试工具
    vbscript能做什么
  • 原文地址:https://www.cnblogs.com/darr/p/5128062.html
Copyright © 2011-2022 走看看