乐趣区

浅拷贝与深拷贝

一、浅拷贝与深拷贝区别

1. 浅拷贝只能实现浅层次的值复制和路径复制,当值为引用类型是传递过去的是一个地址,当改变其中一值时,两者都会发生改变。

2. 深拷贝会对对象进行深层次的复制,也就是当值为引用类型时会循环直到值为基本值类型时才会复制。

3. 实现 jQuery 的 extend 的深浅拷贝功能

// 参数解析
/*
* deep: true 或 false,默认值 false,为 true 时表示深拷贝
* {} 目标对象,多个对象拷贝之后的结果
* {}、{}、{}、{} 被拷贝的对象
*/
function extend(){var target = arguments[0] || {};
    var deep = false;
    var tar = arguments.length;
    var arr = Array.prototype.slice.call(arguments);  
    var i=1;
    var options,src,key,copy;
    var isArray = false;
    if(typeof target === "boolean"){
        deep = target;
        i++;
        target = arguments[1];
    }
    for(;i<arr.length;i++){  // 循环传入的对象数组
        if((options = arr[i] ) != null ){ // 如果当前值不是 null,如果是 null 不做处理
            for(key in options){ //for in 循环对象中 key
                copy = options[key];
                src = target[key];
                // 如果对象中 value 值任然是一个引用类型
                if(deep && ( toString.call( copy) == "[object Object]" || (isArray = toString.call( copy) == "[object Array]") ) ){if( isArray){ // 如果引用类型是数组
                        // 如果目标对象 target 存在当前 key,且数据类型是数组,那就还原此值,如果不是就定义成一个空数组;
                        src = toString.call(src) == "[object Array]" ? src : [];}else{
                        // 如果目标对象 target 存在当前 key,且数据类型是对象,那就还原此值,如果不是就定义成一个空对象;
                        src = toString.call(src) == "[object Object]" ? src : {};}
                    // 引用类型就再次调用 extend,递归,直到此时 copy 是一个基本类型的值。target[key] = extend(deep , src , copy);
                }else if(copy != undefined && copy != src){  // 如果这个值是基本值类型,且不是 undefined
                    target[key] = copy;
                }
            }
        }
    }
    return target;
}
退出移动版