• jquery 源码分析二


    以下这一段函数出现在实例化jQuery对象函数之后,是jQuery的prototype的最基本的几个函数,分析前先看这几个相关的常量和一些函数:

    var deletedIds = [];
    
    var slice = deletedIds.slice;
    
    var concat = deletedIds.concat;
    
    var push = deletedIds.push;
    
    var indexOf = deletedIds.indexOf;
    merge: function( first, second ) {
            var len = +second.length,
                j = 0,
                i = first.length;
    
            while ( j < len ) {
                first[ i++ ] = second[ j++ ];
            }
    
            // Support: IE<9
            // Workaround casting of .length to NaN on otherwise arraylike objects (e.g., NodeLists)
            if ( len !== len ) {
                while ( second[j] !== undefined ) {
                    first[ i++ ] = second[ j++ ];
                }
            }
    
            first.length = i;
    
            return first;
        }
    map: function( elems, callback, arg ) {
            var value,
                i = 0,
                length = elems.length,
                isArray = isArraylike( elems ),
                ret = [];
    
            // 若是数组,则直接从0开始循环,每项都执行callback,返回值保存在ret中
            if ( isArray ) {
                for ( ; i < length; i++ ) {
                    value = callback( elems[ i ], i, arg );
    
                    if ( value != null ) {
                        ret.push( value );
                    }
                }
    
            // 若是对象,就用for in循环,每项执行callback,返回值保存在ret中
            } else {
                for ( i in elems ) {
                    value = callback( elems[ i ], i, arg );
    
                    if ( value != null ) {
                        ret.push( value );
                    }
                }
            }
    
            // 返回ret的副本
            return concat.apply( [], ret );
        }

    首先是最前面的几个常量,先定义了一个空数组,然后后面的几个slice等变量就直接等于了数组的slice操作,这样对于jQuery生成的类数组来说,直接调用这些方法可以很好的处理一些事情。在后面的源码分析中也可以这些函数很多的调用。

    接下来是Jquery下的merge函数(这两个函数都不是在prototype下,而是直接是jQuery的属性),merge函数用于将两个数组或类数组合并,首先是用数组的形式一项项合并,然后为了支持类数组,又加了一个判断,对类数组做支持。

    然后是map函数,map函数对给予的数组或对象进行遍历,针对每一项执行callback函数,ret中保存的是最后callback计算所得的值,组成数组后返回。

    接下来就是jQuery中prototype最初定义的几个函数进行分析,代码和分析如下:

    jQuery.fn = jQuery.prototype = {
        // 定义当前jquery的版本,同时设定好constructor的指向,方便后面使用
        jquery: version,
    
        constructor: jQuery,
    
        // 初始选择器为空
        selector: "",
    
        // 默认的jQuery类数组长度为0
        length: 0,
    
        toArray: function() {
            return slice.call( this );
        },
    
        // 返回指定项的元素
        // 或者返回所有元素组成的数组
        get: function( num ) {
            return num != null ?
    
                // 如果存在num,则返回指定项元素
                ( num < 0 ? this[ num + this.length ] : this[ num ] ) :
    
                // 不存在num,则返回数组副本
                slice.call( this );
        },
    
        // 将一些列的elems放入新的JQuery中
        // 返回的是根据elems生成的新的JQuery
        pushStack: function( elems ) {
    
            // 建立新的JQuery
            var ret = jQuery.merge( this.constructor(), elems );
    
            // 将原始的JQuery对象放入prevObject中,方便后期返回
            ret.prevObject = this;
            ret.context = this.context;
    
            // 返回新生成的对象
            return ret;
        },
    
        // each和map都是对数组或对象进行遍历
        // 两者的区别在于,each遍历时,若某一项callback返回的是false,则停止遍历,最后返回的是经过处理的this
        // map则是将每一项传入的值进行计算,然后将结果组成一个数组返回
        each: function( callback, args ) {
            return jQuery.each( this, callback, args );
        },
    
        map: function( callback ) {
            return this.pushStack( jQuery.map(this, function( elem, i ) {
                return callback.call( elem, i, elem );
            }));
        },
    
        slice: function() {
            return this.pushStack( slice.apply( this, arguments ) );
        },
    
        first: function() {
            return this.eq( 0 );
        },
    
        last: function() {
            return this.eq( -1 );
        },
    
        eq: function( i ) {
            var len = this.length,
                j = +i + ( i < 0 ? len : 0 );
            return this.pushStack( j >= 0 && j < len ? [ this[j] ] : [] );
        },
    
        end: function() {
            return this.prevObject || this.constructor(null);
        },
    
        // 最后的end可以对以上用pushStack过的方法进行回溯,回到上一步的操作对象
        // 以下几个方法的添加使得JQuery更像数组
        push: push,
        sort: deletedIds.sort,
        splice: deletedIds.splice
    };
  • 相关阅读:
    DevExpress v17.2新版亮点—ASP.NET篇(一)
    使用MyEclipse将HTML5移动项目迁移到PhoneGap(一)
    DevExpress v17.2新版亮点—WPF篇(七)
    什么是SpringBoot?
    application.yml中常用参数设置
    什么是MyBatis?
    什么是Spring?
    项目访问路径去掉默认的项目名
    StringUtils常用方法介绍
    Spring学习----自动装配@Resource、@Autowired、@Qualifier
  • 原文地址:https://www.cnblogs.com/cyITtech/p/3579728.html
Copyright © 2020-2023  润新知