资讯专栏INFORMATION COLUMN

jQuery源码学习之extend

quietin / 2983人阅读

摘要:源码学习之用于合并对象,可选择是否深复制。尽管官方文档明确指出第一个参数是的调用情况并不支持,但是这个版本的源码中,判断第一个参数的类型虽有限定是类型,但却未对其值真假加以限定。调用方式源码和指向同一个函数,在函数内部,对调用情况进行区分。

jQuery源码学习之extend

$.extend用于合并对象,可选择是否深复制。使用时,第一个参数为合并后的对象。如果要进行深拷贝,则参数1为true,参数2为要合并的目标对象。尽管jQuery官方文档明确指出第一个参数是false的调用情况并不支持,但是这个版本的源码中,判断第一个参数的类型虽有限定是boolean类型,但却未对其值真假加以限定。所以第一个参数是false也是可行的。

$.fn.extend({})用于拓展jq原型对象,使用只能传入一个对象,多用于jq插件定义。

调用方式
jQuery.extend( target [, object1 ] [, objectN ] )
Query.extend( [deep ], target, object1 [, objectN ] )
jQuery.fn.extend( object )
源码

jQuery.extendjQuery.fn.extend指向同一个函数,在函数内部,对调用情况进行区分。首先判断第一个参数的类型,确定是否显式指定深复制。使用target保存合并对象的引用,如果target不是对象的,要指向空对象。

接着判断参数的个数,区别jQuery.extendjQuery.fn.extend的调用。然后使用for循环,从第二个参数开始遍历,进行拷贝;拷贝时使用src保存target上的属性,copy保存被合并对象上的属性。使用for...in循环遍历属性名进行拷贝,拷贝时忽略对target自身引用,copy为空时也会被忽略,如果根据是否需要深拷贝来决定是否对objectarray递归深拷贝。如果是浅拷贝,直接保存值或引用。

值得一提的是,遍历被合并对象时使用的是for...in循环,所以传入stringarray类型的参数也会被遍历,在合并后对象中的属性名为索引。由于遍历参数是从target后的第一个参数开始,所以先传入的对象会被后传入对象的同名属性覆盖。

jQuery.extend = jQuery.fn.extend = function() {
    // target是对象或true,从第二个参数开始遍历
    var options, name, src, copy, copyIsArray, clone,
        target = arguments[ 0 ] || {},
        i = 1,
        length = arguments.length,
        deep = false;

    // Handle a deep copy situation
    // 第一个参数如果是boolean,表明显示指定是否深复制
    if ( typeof target === "boolean" ) {
        deep = target;

        // Skip the boolean and the target
        // 将target指向第一个参数,从第三个参数开始合并
        target = arguments[ i ] || {};
        i++;
    }

    // Handle case when target is a string or something (possible in deep copy)
    // 不是对象或函数,将target设置默认空
    if ( typeof target !== "object" && !jQuery.isFunction( target ) ) {
        target = {};
    }

    // Extend jQuery itself if only one argument is passed
    // 只有一个参数,即$.fn.extend({}),target指向jq原型
    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...in会遍历数组或字符串
            // src为target属性值,copy为闯入对象的属性值
            for ( name in options ) {
                src = target[ name ];
                copy = options[ name ];

                // Prevent never-ending loop
                // 自身的属性指向自身,这种情况避免无限循环,跳过自身引用的复制
                if ( target === copy ) {
                    continue;
                }

                // Recurse if we"re merging plain objects or arrays
                // 深复制时,调用$.extend递归调用。
                // 复制时保存属性的原始类型,只有对象或数组才必要进行深复制
                if ( deep && copy && ( jQuery.isPlainObject( copy ) ||
                    ( copyIsArray = Array.isArray( copy ) ) ) ) {

                    if ( copyIsArray ) {
                        copyIsArray = false;
                        clone = src && Array.isArray( src ) ? src : [];

                    } else {
                        clone = src && jQuery.isPlainObject( src ) ? src : {};
                    }

                    // Never move original objects, clone them
                    target[ name ] = jQuery.extend( deep, clone, copy );

                // Don"t bring in undefined values
                // 浅复制,值非空直接复制或保存引用
                } else if ( copy !== undefined ) {
                    target[ name ] = copy;
                }
            }
        }
    }

    // Return the modified object
    return target;
};

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/96358.html

相关文章

  • jQuery源码习之event

    摘要:回调队列中的元素是对象,代表一个事件回调,拥有多个属性,如等等,其中是回调函数,在触发时通过传递,具体的在后面讲。类型是时键表示事件名,规则同上,键值表示事件触发时的回调函数。 jQuery源码学习之event jQuery的事件机制为异步回调,事件监听的属性、参数和回调的等保存在Data实例中,在元素上保存该对象的引用。有方法handle,内部执行dispatch;有属性events...

    XboxYan 评论0 收藏0
  • jQuery源码习之Callbacks

    摘要:源码学习之的通过回调实现异步,其实现核心是。回调函数队列中的函数返回时停止触发回调函数队列只能被触发一次记录上一次触发队列传入的值,新添加到队列中的函数使用记录值作为参数,并立即执行。实际是,内部则调用了在定义的局部函数。 jQuery源码学习之Callbacks jQuery的ajax、deferred通过回调实现异步,其实现核心是Callbacks。 使用方法 使用首先要先新建一个...

    lmxdawn 评论0 收藏0
  • Javascript设计模式习之Decorator(装饰者)模式

    摘要:抽象模式使用的装饰者模式允许我们在运行时或者在随后一个点上动态地将两个或两个以上的对象和它们的属性一起扩展或合并为一个单一对象。定义三个对象目的是为了装饰对象将的额外功能附加到上。 抽象decorator模式 使用jQuery的装饰者模式 jQuery.extend()允许我们在运行时或者在随后一个点上动态地将两个或两个以上的对象(和它们的属性)一起扩展(或合并)为一个单一对象。 定义...

    Joyven 评论0 收藏0
  • java第三方包习之jsoup

    摘要:下面隆重介绍简介是一个解析的第三方库,它提供了一套非常方便的,可使用,以及类的操作方法来取出和操作数据。一个文档的对象模型文档由多个和组成其继承结构如下继承继承继承一个包含一个子节点集合,并拥有一个父。 前言 使用python写爬虫的人,应该都听过beautifulsoup4这个包,用来它来解析网页甚是方便。那么在java里有没有类似的包呢?当然有啦!而且也非常好用。下面隆重介绍jso...

    dackel 评论0 收藏0
  • 集合框架源码习之ArrayList

    摘要:用户自己指定容量创建大小的数组创建空数组默认构造函数,其默认初始容量为构造一个包含指定集合的元素的列表,按照它们由集合的迭代器返回的顺序。以正确的顺序返回该列表中的元素的迭代器。此方法充当基于阵列和基于集合的之间的桥梁。 目录: 0-0-1. 前言 0-0-2. 集合框架知识回顾 0-0-3. ArrayList简介 0-0-4. ArrayList核心源码 0-0-5. Ar...

    BLUE 评论0 收藏0

发表评论

0条评论

quietin

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<