jQuery中怎么实现一个构造器

这篇文章给大家介绍jQuery中怎么实现一个构造器,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。

成都网站建设哪家好,找成都创新互联!专注于网页设计、重庆网站建设公司、微信开发、微信小程序开发、集团成都定制网站等服务项目。核心团队均拥有互联网行业多年经验,服务众多知名企业客户;涵盖的客户类型包括:白乌鱼等众多领域,积累了大量丰富的经验,同时也获得了客户的一致好评!

2009-01-13发布的1.3版

init: function( selector, context ) {     // Make sure that a selection was provided        selector = selector || document;          // 处理节点参数,直接添加属性到新实例上        if ( selector.nodeType ) {            this[0] = selector;            this.length = 1;            this.context = selector;            return this;        }        // 处理字符串参数        if ( typeof selector === "string" ) {            // 判定是否为HTML片断还是ID            var match = quickExpr.exec( selector );                if ( match && (match[1] || !context) ) {                 // 如果是HTML片断,转换一个由节点构造的数组                if ( match[1] )                   selector = jQuery.clean( [ match[1] ], context );                   // 如果是ID,则查找此元素,如果找到放进空数组中                else {                    var elem = document.getElementById( match[3] );                     // Make sure an element was located                    if ( elem ){                        // 处理 IE and Opera 混淆ID与NAME的bug                        if ( elem.id != match[3] )                            return jQuery().find( selector );                        var ret = jQuery( elem );                        ret.context = document;                        ret.selector = selector;                        return ret;                    }                    selector = [];                }            } else           //使用Sizzle处理其他CSS表达式,生成实例并返回                return jQuery( context ).find( selector );            // 处理函数参数,直接domReady        } else if ( jQuery.isFunction( selector ) )            return jQuery( document ).ready( selector );         //处理jQuery对象参数,简单地将其两个属性赋给新实例        if ( selector.selector && selector.context ) {            this.selector = selector.selector;            this.context = selector.context;        }        //将上面得到节点数组,用setArray方法把它们变成实例的元素        return this.setArray(jQuery.makeArray(selector));    },

2009-02-19发布的1.32版

init: function( selector, context ) {        // Make sure that a selection was provided        selector = selector || document;        // 处理节点参数,直接添加属性到新实例上        if ( selector.nodeType ) {            this[0] = selector;            this.length = 1;            this.context = selector;            return this;        }         //处理字符串参数        if ( typeof selector === "string" ) {            //判定是否为HTML片断还是ID            var match = quickExpr.exec( selector );            if ( match && (match[1] || !context) ) {               // 如果是HTML片断,转换一个由节点构造的数组                if ( match[1] )                    selector = jQuery.clean( [ match[1] ], context );                else {                    var elem = document.getElementById( match[3] );                     // 如果是ID,则查找此元素,如果找到放进空数组中                    if ( elem && elem.id != match[3] )                      return jQuery().find( selector );                       //这里对1.3版做了些优化,更简洁                    var ret = jQuery( elem || [] );                    ret.context = document;                    ret.selector = selector;                    return ret;                }            } else               //使用Sizzle处理其他CSS表达式,生成实例并返回                return jQuery( context ).find( selector );               // 处理函数参数,进行domReady操作        } else if ( jQuery.isFunction( selector ) )            return jQuery( document ).ready( selector );            //处理jQuery对象参数,简单地将其两个属性赋给新实例        if ( selector.selector && selector.context ) {            this.selector = selector.selector;            this.context = selector.context;        }    //这里对1.3版做了些扩展,允许传珍上元素集合(HTMLCollection)与节点集合(NodeList),    //元素数组可能是我们用字符串转换过来的,也可以是用户直接传进来的        return this.setArray(jQuery.isArray( selector ) ? selector : jQuery.makeArray(selector));    },

2010-01-13发布的1.4版

init: function( selector, context ) {        var match, elem, ret, doc;        //处理空白字符串,null,undefined参数(新增),返回一个非常纯净的实例        if ( !selector ) {            return this;        }        // 处理节点参数,直接添加属性到新实例上        if ( selector.nodeType ) {            this.context = this[0] = selector;//写法上优化            this.length = 1;            return this;        }        //处理字符串参数        if ( typeof selector === "string" ) {            //  判定是否为HTML片断还是ID            match = quickExpr.exec( selector );            if ( match && (match[1] || !context) ) {                //如果是HTML片断                if ( match[1] ) {                    //取得文档对象                    doc = (context ? context.ownerDocument || context : document);                    // 如果是单个标签,直接使用 document.createElement创建此节点并放入数组中                    ret = rsingleTag.exec( selector );                    if ( ret ) {                        //如果后面跟着一个纯净的JS对象,则为此节点添加相应的属性或样式                        if ( jQuery.isPlainObject( context ) ) {                            selector = [ document.createElement( ret[1] ) ];                            jQuery.fn.attr.call( selector, context, true );                        } else {                            selector = [ doc.createElement( ret[1] ) ];                        }                    } else {                        //改由buildFragment来生成节点集合(NodeList)                        ret = buildFragment( [ match[1] ], [ doc ] );                        selector = (ret.cacheable ? ret.fragment.cloneNode(true) : ret.fragment).childNodes;                    }                } else {                    // 如果是ID,则查找此元素,如果找到放进空数组中                    elem = document.getElementById( match[2] );                    if ( elem ) {                       // 处理 IE and Opera 混淆ID与NAME的bug                        if ( elem.id !== match[2] ) {                            return rootjQuery.find( selector );                        }                        //这里也做了一些优化,原来是很傻地再生成一个jQuery实例                        this.length = 1;                        this[0] = elem;                    }                    this.context = document;                    this.selector = selector;                   return this;                }                   // 如果字符是很简单的标签选择器,那基本没有必要走Sizzle路线,直接getElementsByTagName,很好的优化            } else if ( !context && /^\w+$/.test( selector ) ) {                this.selector = selector;                this.context = document;                selector = document.getElementsByTagName( selector );                // 如果第二个参数不存在或者是jQuery对象,那么用它或rootjQuery调用find查找目标节点(走Sizzle路线)            } else if ( !context || context.jquery ) {                return (context || rootjQuery).find( selector );                // HANDLE: $(expr, context)                // (which is just equivalent to: $(context).find(expr)            } else {                //如果第二个参数已指定为某元素节点,转为jQuery对象,走Sizzle路线                return jQuery( context ).find( selector );            }               // 处理函数参数,直接domReady        } else if ( jQuery.isFunction( selector ) ) {            return rootjQuery.ready( selector );        }        //处理jQuery对象参数,简单地将其两个属性赋给新实例        if (selector.selector !== undefined) {            this.selector = selector.selector;            this.context = selector.context;        }     //这里又做了些许修改,缘于makeArray可以接受第二个参数(可以是数组或类数组,这时相当合并操作)        return jQuery.isArray( selector ) ?            this.setArray( selector ) ://内部用push方法,迅速将一个普通对象变成类数组对象            jQuery.makeArray( selector, this );    },

接着是广受欢迎的2010-02-13发布的1.42版

init: function( selector, context ) {        var match, elem, ret, doc;       // 处理空白字符串,null,undefined参数        if ( !selector ) {            return this;        }        // 处理节点参数        if ( selector.nodeType ) {            this.context = this[0] = selector;            this.length = 1;            return this;        }           // 处理body参数(新增)        if ( selector === "body" && !context ) {            this.context = document;            this[0] = document.body;            this.selector = "body";            this.length = 1;            return this;        }        // 处理字符串参数,分七种情形:        //①单个标签,带对象属性包           --->   jQuery.merge        //②单个标签,不带对象属性包         --->   attr + jQuery.merge        //③复杂的HTML片断                 --->   buildFragment + jQuery.merge        //④ID选择器,与找到的元素的ID不同   --->   getElementById + Sizzle + pushStack        //⑤ID选择器,与找到的元素的ID相同   --->   getElementById + 简单属性添加        //⑥标签选择器                     --->   getElementsByTagName + jQuery.merge        //⑦其他CSS表达式                  --->   Sizzle + pushStack        if ( typeof selector === "string" ) {            match = quickExpr.exec( selector );            if ( match && (match[1] || !context) ) {                if ( match[1] ) {                    doc = (context ? context.ownerDocument || context : document);                    ret = rsingleTag.exec( selector );                    if ( ret ) {                      if ( jQuery.isPlainObject( context ) ) {                            selector = [ document.createElement( ret[1] ) ];                            jQuery.fn.attr.call( selector, context, true );                        } else {                            selector = [ doc.createElement( ret[1] ) ];                        }                    } else {                        ret = buildFragment( [ match[1] ], [ doc ] );                        selector = (ret.cacheable ? ret.fragment.cloneNode(true) : ret.fragment).childNodes;                    }                    return jQuery.merge( this, selector );                } else {                    elem = document.getElementById( match[2] );                    if ( elem ) {                        if ( elem.id !== match[2] ) {                            return rootjQuery.find( selector );                        }                        this.length = 1;                        this[0] = elem;                    }                    this.context = document;                    this.selector = selector;                    return this;                }            } else if ( !context && /^\w+$/.test( selector ) ) {                this.selector = selector;                this.context = document;                selector = document.getElementsByTagName( selector );                return jQuery.merge( this, selector );            } else if ( !context || context.jquery ) {                return (context || rootjQuery).find( selector );            } else {               return jQuery( context ).find( selector );            }            // 处理函数参数,直接domReady        } else if ( jQuery.isFunction( selector ) ) {            return rootjQuery.ready( selector );        }        //处理jQuery对象参数        if (selector.selector !== undefined) {            this.selector = selector.selector;            this.context = selector.context;        }        //无论是数组还是类数组(如NodeList),统统使用jQuery.makeArray来为实例添加新的元素        return jQuery.makeArray( selector, this );    },

另附上makeArray方法与merge方法,merge方法好神奇啊

makeArray: function( array, results ) {        var ret = results || [];         if ( array != null ) {            // The window, strings (and functions) also have 'length'            // The extra typeof function check is to prevent crashes            // in Safari 2 (See: #3039)            if ( array.length == null || typeof array === "string" || jQuery.isFunction(array) || (typeof array !== "function" && array.setInterval) ) {                push.call( ret, array );            } else {                jQuery.merge( ret, array );            }        }        return ret;    },    merge: function( first, second ) {        var i = first.length, j = 0;         if ( typeof second.length === "number" ) {            for ( var l = second.length; j < l; j++ ) {                first[ i++ ] = second[ j ];            }        } else {            while ( second[j] !== undefined ) {                first[ i++ ] = second[ j++ ];            }        }        first.length = i;        return first;    },

2011-01-23发布的1.5版,其init方法与1.42的变化不大:只有两处做了改动:

//1.42    -  ret = buildFragment( [ match[1] ], [ doc ] );    -  selector = (ret.cacheable ? ret.fragment.cloneNode(true) : ret.fragment).childNodes;    //1.5    + ret = jQuery.buildFragment( [ match[1] ], [ doc ] );    + selector = (ret.cacheable ? jQuery.clone(ret.fragment) : ret.fragment).childNodes;    //1.42    - return jQuery( context ).find( selector );    //1.5    + return this.constructor( context ).find( selector );//目的就是为了不再生成新实例

2011-05-02发布的jquery1.6,变化不大,只是对HTML片断进行了更严密的判定:

// Are we dealing with HTML string or an ID?       if ( selector.charAt(0) === "<" && selector.charAt( selector.length - 1 ) === ">" && selector.length >= 3 ) {      // Assume that strings that start and end with <> are HTML and skip the regex check        match = [ null, selector, null ];       } else {        match = quickExpr.exec( selector );       }

关于jQuery中怎么实现一个构造器就分享到这里了,希望以上内容可以对大家有一定的帮助,可以学到更多知识。如果觉得文章不错,可以把它分享出去让更多的人看到。


文章名称:jQuery中怎么实现一个构造器
文章起源:http://scyanting.com/article/ijsiee.html