深拷贝和浅拷贝

1.JQuery中的深拷贝和浅拷贝

$.extend(true,a,b);

判断依据:是否在参数中存在第一个参数true参数

JQ中的extend码源


jQuery.extend = jQuery.fn.extend = function() {

 

    var options, name, src, copy, copyIsArray, clone,

        target = arguments[0] || {},

        i = 1,

        length = arguments.length,

        deep = false;

    /*

    变量 options:指向某个源对象。

    变量 name:表示某个源对象的某个属性名。

    变量 src:表示目标对象的某个属性的原始值。

    变量 copy:表示某个源对象的某个属性的值。

    变量 copyIsArray:指示变量 copy 是否是数组。

    变量 clone:表示深度复制时原始值的修正值。

    变量 target:指向目标对象,申明时先临时用第一个参数值。

    变量 i:表示源对象的起始下标,申明时先临时用第二个参数值。

    变量 length:表示参数的个数,用于修正变量 target。

    变量 deep:指示是否执行深度复制,默认为 false。



    ps:源对象指的是把自己的值付给别人的对象;目标对象指的是被源对象赋值的对象

    */

 

    // 如果第一个参数传入的是布尔值

    if ( typeof target === "boolean" ) {

        deep = target;//设置deep变量,确定是深拷贝还是浅拷贝

        target = arguments[1] || {};//将目标对象设为第二个参数值。

        i = 2;//源对象的起始下标设为2(即从第三个参数开始算源对象)

    }

 

    // Handle case when target is a string or something (possible in deep copy)

    //嗯,原英文解释的很清楚

    if ( typeof target !== "object" && !jQuery.isFunction(target) ) {

        target = {};

    }

 

    // 如果没有目标对象,那么目标对象就是jquery对象

    if ( length === i ) {

        target = this;

        --i;

    }

 

    拷贝的核心部分代码

    for ( ; i < length; i++ ) {//遍历源对象

        // Only deal with non-null/undefined values

        if ( (options = arguments[ i ]) != null ) {//options就是源对象

            // Extend the base object

            for ( name in options ) {//遍历源对象的属性名

                src = target[ name ];//获取目标对象上,属性名对应的属性

                copy = options[ name ];//获取源对象上,属性名对应的属性

 

                // 如果复制值copy 与目标对象target相等,

                //为了避免深度遍历时死循环,因此不会覆盖目标对象的同名属性。

                if ( target === copy ) {

                    continue;

                }

 

                //递归地将源对象上的属性值合并到目标对象上

                //如果是深拷贝,且待拷贝的对象存在,且是普通对象或是数组

                //这一个判断条件非常关键,这正是之前疑问的症结

                //首先,普通对象的定义是:通过 "{}" 或者 "new Object" 创建的

                //回到之前的疑问,目标对象tobeCloned的属性o对象的obj不是普通对象,也不是数组,所以程序不会走到下面的分支

                if ( deep && copy && ( jQuery.isPlainObject(copy) || (copyIsArray = jQuery.isArray(copy)) ) ) {

                    if ( copyIsArray ) {

                        //如果是数组

                        copyIsArray = false;

                        clone = src && jQuery.isArray(src) ? src : [];

 

                    } else {

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

                    }

 

                    // 递归地拷贝

                    target[ name ] = jQuery.extend( deep, clone, copy );

 

                } else if ( copy !== undefined ) {

                //会走到这个分支,这个分支的处理很暴力,就是把源对象的属性,直接赋给源对象。

                //对于上文中tobeCloned对象的属性o,没有进一步递归地拷贝,而是直接把引用赋给源对象

                //所以改变tobeCloned的o属性时,目标对象的o属性也被改变了。

                    target[ name ] = copy;

                }

            }

        }

    }

 

    // Return the modified object

    return target;

};

深拷贝和浅拷贝:

对于对象来说,浅拷贝只是对象地址的复制,并没有开辟新的栈,也就是说两个对象指向同一个地址,修改其中一个另一个也会随之改变;深拷贝是会开辟新的栈,两个对象不同地址,修改不会影响

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值