jQuery源码研究分析学习笔记-jQuery原型属性和方法(九)

jQuery的一些其他原型属性和方法介绍:

jQuery.fn = jQuery.prototype = {
    constructor: jQuery,
    init: function( selector, context, rootjQuery ) {
    //省略...
    },

    // 记录jQuery查找和过滤DOM元素时的选择器表达式,但不一定是可执行的选择器表达式,为了方便调试
    selector: "",

    // 属性jquery表示使用的jQuery版本号
    jquery: "1.7.2",

    // length表示当前jQuery对象中元素的个数
    length: 0,

    // 返回当前jQuery对象中元素的个数,跟 .length功能一样,但是需要调用函数,建议优先使用.length
    size: function() {
        return this.length;
    },

    //将当前jQuery对象转换成为数组,借用了数组的slice()方法
    //slice = Array.prototype.slice
    toArray: function() {
        return slice.call( this, 0 );
    },

    // 返回当前jQuery对象中指定位置的元素或包含了全部元素的数组
    get: function( num ) {
        return num == null ?

            // 没有传入参数,返回整个包含所有元素的数组
            this.toArray() :

            // 负数表示从元素集合的末尾开始计算
            ( num < 0 ? this[ this.length + num ] : this[ num ] );
    },

    // elems:将放入新的jQuery对象的元素数组
    // name: 产生元素数组elems的jQUery方法名
    //selector:传给jQuery方法的参数,用于修正原型属性.selector
    pushStack: function( elems, name, selector ) {
        // 构造一个新的空jQuery对象ret,this.constructor指向构造函数jQuery
        var ret = this.constructor();

        if ( jQuery.isArray( elems ) ) {
        //把elems合并到ret中,如果参数elems是数组,借用数组push方法插入,
            push.apply( ret, elems );

        } else {

        //调用jQuery.merge()方法合并
            jQuery.merge( ret, elems );
        }

        // 给ret设置属性prevObject,并指向当前jQuery对象,从而形成一个链式栈
        ret.prevObject = this;

        //在新jQuery对象ret导航设置属性prevObject,指向当前jQuery对象的上下文,后续的jQuery方法可能会用到这个属性
        ret.context = this.context;

        //在ret设置属性selector
        if ( name === "find" ) {
            ret.selector = this.selector + ( this.selector ? " " : "" ) + selector;
        } else if ( name ) {
            ret.selector = this.selector + "." + name + "(" + selector + ")";
        }

        // 返回新jQuery对象ret
        return ret;
    },


    // 遍历当前的jquery对象,并在每个元素上执行回调函数,调用静态方法jQuery.each()实现
    each: function( callback, args ) {
        return jQuery.each( this, callback, args );
    },

    ready: function( fn ) {
        // Attach the listeners
        jQuery.bindReady();

        // Add the callback
        readyList.add( fn );

        return this;
    },

    eq: function( i ) {
        i = +i;
        return i === -1 ?
            this.slice( i ) :
            this.slice( i, i + 1 );
    },

    first: function() {
        return this.eq( 0 );
    },

    last: function() {
        return this.eq( -1 );
    },

    //先借用数组方法slice()从当前jQuery对对象中获取指定范围的子集,再调用方法.pushStack()把子集转换为jQuery对象,同时通过属性prevObject保留了对当前jQuery对象的引用
    slice: function() {
        return this.pushStack( slice.apply( this, arguments ),
            "slice", slice.call(arguments).join(",") );
    },

    //方法.map()遍历当前对象,在每个元素上执行回调函数,并将回调函数的返回值放入一个新jQuery对象中,该方法常用于获取或设置DOM元素集合的值
    //主要是通过静态方法jQuery.map()和原型方法.pushStack()实现
    map: function( callback ) {
        return this.pushStack( jQuery.map(this, function( elem, i ) {
            return callback.call( elem, i, elem );
        }));
    },

    //返回前一个jQuery对象。如果不存在,则构建一个空的jQuery对象返回
    end: function() {
        return this.prevObject || this.constructor(null);
    },

    //push(),向当前jQuery对象的末尾添加新元素,并返回新长度
    push: push,  
    sort: [].sort,
    splice: [].splice //向当前jQuery对象中插入、删除或替换元素
};

jQuery.each()方法是一个静态方法,是一个通用的遍历迭代方法,用于遍历对象和数组,对于数组和含有length属性的类数组对象,该方法通过下标遍历,从0到length-1;对于其他对象则通过属性名遍历,在遍历过程中,如果回回调函数返回false,则结束遍历

//object:待遍历的对象或数组
//callback:回调函数,会在数组的每个元素或对象的每个属性上执行
//args: 传给回调函数的参数数组,可以选,如果没有传入args,则执行回调函数时会传入两个参数下标和对应的元素或属性名和对应的属性值,如果传入args,则只把该参数传给回调函数
    each: function( object, callback, args ) {
        var name, i = 0,
            length = object.length,
            //isObj表示参数是object是对象还是数组
            isObj = length === undefined || jQuery.isFunction( object );

        if ( args ) {
            if ( isObj ) {

            //对于对象,通过for-in循环遍历属性名
                for ( name in object ) {

                        //执行回调函数时通过apply()方法,指定this关键字所引用的对象,同时要求并假设参数args是数组
                    if ( callback.apply( object[ name ], args ) === false ) {
                        break;
                    }
                }
            } else {
                //类数组或数组用for循环遍历
                for ( ; i < length; ) {
                    if ( callback.apply( object[ i++ ], args ) === false ) {
                        break;
                    }
                }
            }

        // A special, fast, case for the most common use of each
        } else {
            //未传入参数args
            if ( isObj ) {
                //对象,通过for-in循环遍历属性名
                //执行回调函数时,通过方法call()指定this关键字所引用的对象
                for ( name in object ) {
                    if ( callback.call( object[ name ], name, object[ name ] ) === false ) {
                        break;
                    }
                }
            } else {
                for ( ; i < length; ) {
                    if ( callback.call( object[ i ], i, object[ i++ ] ) === false ) {
                        break;
                    }
                }
            }
        }

        //返回传入的参数object
        return object;
    }

jQuery.map(elems, callback, arg)是静态方法,主要对数组中的每个元素或对象的每个属性调用一个回调函数,并将回调函数的返回值放如一个新的数组中。执行回调函数时传入两个参数:数组元素或属性值,元素下标或属性名。关键字this指向全局对象window,回调函数的返回值会被放入新的数组中,

// elems:待遍历的数组或对象
//callback: 回调函数,会在数组的每个元素或对象的每个属性上执行。执行时传入两个参数
//arg:仅限于jQuery内部使用,如果调用jQuery.map()时传入了参数arg,则该参数会被传给回调函数
    map: function( elems, callback, arg ) {
        var value, key, ret = [],
            i = 0,
            length = elems.length,
            // 判断参数elems是否是数组,一变决定遍历方式
            isArray = elems instanceof jQuery || length !== undefined && typeof length === "number" && ( ( length > 0 && elems[ 0 ] && elems[ length -1 ] ) || length === 0 || jQuery.isArray( elems ) ) ;

        // 对于数组或类数组对象,通过for循环遍历下标,
        if ( isArray ) {
            for ( ; i < length; i++ ) {
                value = callback( elems[ i ], i, arg );
                //如果回调函数的返回值不是null和undefined,则把返回值放入结果集ret
                if ( value != null ) {
                    ret[ ret.length ] = value;
                }
            }

        // 若是对象,则通过for -in 循环遍历属性名,为每个属性值执行返回回调函数,
        } else {
            for ( key in elems ) {

                value = callback( elems[ key ], key, arg );

                //如果回调函数的返回值不是null和undefined,则把返回值放入结果集ret
                if ( value != null ) {
                    ret[ ret.length ] = value;
                }
            }
        }

        // 最后在空数组[]上调用方法concat()扁平化结果集ret中元素,并返回
        return ret.concat.apply( [], ret );
    }

你可能感兴趣的:(jQuery,源码研究)