美文网首页
深拷贝和浅拷贝

深拷贝和浅拷贝

作者: 婷楼沐熙 | 来源:发表于2017-03-07 09:38 被阅读52次

深复制和浅复制只针对像 Object, Array 这样的复杂对象。简单来说,浅复制只复制一层对象的属性,而深复制则递归复制了所有层级。

一、浅拷贝

let obj = {a: 1, b: [2,3]}
function shadowCopy (obj) {
    var newObj = {};
    for(let prop in obj) {
        if(obj.hasOwnProperty(prop)) {
            newObj[prop] = obj[prop];
        }
    }
    return newObj;
}
let shadowObj = shadowCopy(obj);

因为浅复制只会将对象的各个属性进行依次复制,并不会进行递归复制。而 JavaScript 存储对象都是存地址的,所以浅复制会导致 obj.arr 和 shadowObj.arr 指向同一块内存地址。

二、深拷贝

  • 深拷贝则是复制变量值,对于非基本类型的变量,则递归至基本类型变量后,再复制。它不仅将原对象的各个属性逐个复制出去,而且将原对象各个属性所包含的对象也依次采用深复制的方法递归复制到新对象上。这就不会存在上面 obj 和 shadowObj 的 arr 属性指向同一个对象的问题。
let simpleObj = {
    a:1,
    b:{
        b1:1
    },
    c:[
        {
            c1:1
        }
    ]
 };
let simpleArr=[
    {
        a:[1,2,3]
    },
    {
        b:1
    },
    {
        p:[1,2]
    }
 ]
let deepCopy = function (targetObj) {
    let copiedObj = Array.isArray(targetObj) ? [] : {};
    let ArrayDealer = function(arrayVal, copiedObj) {
        arrayVal.forEach(function(arrVal, index) {
            copiedObj[index] = {};
            console.log(arrVal);
            if(typeof arrVal == 'object') {
                copy(arrval[index], copiedObj[index]);
            }else{
                copiedObj[index] = arrVal;
            }
        })
    };
    let ObjectDealer = function (targetObj, copiedObj) {
        for(var key in targetObj) {
            var val = targetObj[key];
            copiedObj[key] = {};
            //非引用类型节点
            if(typeof val=='object'){
                copy(val,copiedObj[key]);
            }else{
               copiedObj[key] = val;
            }
        }
    }
    let copy = function (targetObj, copiedObj) {
        if(Array.isArray(targetObj)) {
            ArrayDealer(targetObj, copiedObj);
        }else{
            ObjectDealer(targetObj, copiedObj);
        }
    }
    copy(targetObj, copiedObj);
    return copiedObj; 
}
console.log(deepCopy(simpleObj));
console.log(deepCopy(simpleArr));
  • 还有一种方法是借助JSON 全局对象,针对纯 JSON 数据对象的深复制,正确处理的对象只有 Number, String, Boolean, Array, 扁平对象,即那些能够被 json 直接表示的数据结构。
    下面的例子是深拷贝对象和数组。
var cloneObj = function(obj){
    var str, newobj = obj.constructor === Array ? [] : {};
    if(typeof obj !== 'object'){
        return;
    } else if(window.JSON){
        str = JSON.stringify(obj), //系列化对象
        newobj = JSON.parse(str); //还原
    } else {
        for(var i in obj){
            newobj[i] = typeof obj[i] === 'object' ? 
            cloneObj(obj[i]) : obj[i]; 
        }
    }
  • 也可以用jQuery的extend
var x = {
    a: 1,
    b: { f: { g: 1 } },
    c: [ 1, 2, 3 ]
};

var y = $.extend({}, x),          //shallow copy
    z = $.extend(true, {}, x);    //deep copy

y.b.f === x.b.f       // true
z.b.f === x.b.f       // false

相关文章

  • iOS深拷贝(MutableCopy)与浅拷贝(Copy)的区别

    深拷贝和浅拷贝的概念 iOS中有深拷贝和浅拷贝的概念,那么何为深拷贝何为浅拷贝呢?浅拷贝:浅拷贝并不拷贝对象本身,...

  • iOS面试题-第二页

    11.深拷贝和浅拷贝的理解. 深拷贝;拷贝的内容. 浅拷贝:拷贝的指针. 深拷贝如: NSMutableDicti...

  • iOS - copy 与 mutableCopy

    一说到拷贝,就不得不提浅拷贝和深拷贝。 何谓浅拷贝?何谓深拷贝? 往简单的说: 浅拷贝:拷贝地址。 深拷贝:拷贝内...

  • JS中的深拷贝与浅拷贝

    知乎:js中的深拷贝和浅拷贝? 掘金: js 深拷贝 vs 浅拷贝 前言 首先深拷贝与浅拷贝只针对 Object,...

  • iOS--拷贝相关题

    1、什么是深拷贝什么是浅拷贝?浅拷贝和深拷贝的区别 * 浅拷贝(shallow copy):指针拷贝,对于被拷贝对...

  • copy和mutableCopy的区别

    copy和mutableCopy的区别 深拷贝和浅拷贝的区别 在OC中对象的拷贝方式有两种:深拷贝和浅拷贝.浅拷贝...

  • 2018-10-10函数基础

    深拷贝和浅拷贝 深拷贝 copy.deepcopy(对象)浅拷贝 copy.copy(对象)深拷贝: 将对象对应的...

  • Objective-C中的浅拷贝和深拷贝

    Objective-C中的浅拷贝和深拷贝 Objective-C中的浅拷贝和深拷贝

  • JavaScript的深拷贝和浅拷贝

    原文 博客原文 大纲 前言1、对深拷贝和浅拷贝的初步认识2、深拷贝和浅拷贝的区别3、浅拷贝存在的缺陷4、深拷贝的实...

  • java中的深拷贝和浅拷贝

    简单记录一下java中的深拷贝和浅拷贝,深拷贝和浅拷贝只是针对对象而言的. 1 深拷贝代码 2 浅拷贝代码 3 测...

网友评论

      本文标题:深拷贝和浅拷贝

      本文链接:https://www.haomeiwen.com/subject/qbxjgttx.html