(177-240)

extend方法

jQuery.extend = jQuery.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 ];



                // 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 : [];

                        console.log(clone)



                    } 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;

};



//合并对象到第一个对象

console.log(jQuery.extend({b:2},{d:3},{b:3,c:1}))

//合并数组

console.log(jQuery.extend([1,[1,3]],[1,[1,2]]))

//递归合并

console.log(jQuery.extend(true,{a:1,b:{c:1}},{b:[2]},{c:1}))

//参数为1时

jQuery.extend({a:1})

console.log(jQuery.a)

extend方法的功能要求:

~合并多个对象到第一个对象

~递归合并模式

~参数为1个时,对this指向的对象(调用者,jQuery或者jQuery.fn)进行扩展

~合并数组

实际功能要求很简单,就是遍历参数合并对象到首对象。其它作者考虑的问题有,对象和数字同时出现,参数为字符串,等bug兼容处理。

不只是针对jQuery,对任何源码,开发团队一般会尽可能解决多的情况。都知道,先有问题才有解决办法。如果有些问题我们不知道怎么回事,我们读起解决办法也就莫名其妙。

这个并不需要太纠结,在今后,当你碰到相同的问题时,你会自然写出相同的代码。

下面是只进行递归的扩展函数,原理是判断目标属性是不是对象,是则递归,不是则直接合并。

function extend(){

    var target = arguments[0];

    var options = arguments[i];

    for( var i = 1;i<arguments.length;i++){

        for(var name in (options = arguments[i])){

            var src = target[name]

            var copy = options[name]

            //如果是对象,则继续递归

            if(jQuery.isPlainObject(copy)){

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

                extend(clone,copy)

            }else{

                //不是则合并

                target[name] = arguments[i][name];

            }

        }

    }

    return target;

}

console.log(extend({a:{b:1}},{a:{c:2}}))

 

你可能感兴趣的:((177-240))