1. 程式人生 > 實用技巧 >51.深拷貝和淺拷貝的區別?如何實現

51.深拷貝和淺拷貝的區別?如何實現

淺拷貝的四種方式:

深拷貝:

JS實現深拷貝https://www.cnblogs.com/dobeco/p/11295316.html

一、賦值、淺拷貝與深拷貝的區別

二、深拷貝的方法

1.JSON轉換

var targetObj = JSON.parse(JSON.stringify(copyObj))
let arr4 = JSON.parse(JSON.stringify(arr))

缺點:

(1)如果物件裡有函式,函式無法被拷貝下來

(2)無法拷貝copyObj物件原型鏈上的屬性和方法

(3)當資料的層次很深,會棧溢位

2.普通遞迴函式

function deepCopy( source ) {
if (!isObject(source)) return source; //如果不是物件的話直接返回
    let target = Array.isArray( source ) ? [] : {} //陣列相容
    for ( var k in source ) {
    	if (source.hasOwnProperty(k)) {
    		if ( typeof source[ k ] === 'object' ) {
            	target[ k ] = deepCopy( source[ k ] )
        	} else {
            	target[ k ] = source[ k ]
        	}
    	}
    }
    return target
}

function isObject(obj) {
    return typeof obj === 'object' && obj !== null
}

缺點:

(1)無法保持引用

(2)當資料的層次很深,會棧溢位

3.防棧溢位函式

function cloneLoop(x) {
    const root = {};

    // 棧
    const loopList = [
        {
            parent: root,
            key: undefined,
            data: x,
        }
    ];

    while(loopList.length) {
        // 深度優先
        const node = loopList.pop();
        const parent = node.parent;
        const key = node.key;
        const data = node.data;

        // 初始化賦值目標,key為undefined則拷貝到父元素,否則拷貝到子元素
        let res = parent;
        if (typeof key !== 'undefined') {
            res = parent[key] = {};
        }

        for(let k in data) {
            if (data.hasOwnProperty(k)) {
                if (typeof data[k] === 'object') {
                    // 下一次迴圈
                    loopList.push({
                        parent: res,
                        key: k,
                        data: data[k],
                    });
                } else {
                    res[k] = data[k];
                }
            }
        }
    }

    return root;
}

優點:

(1)不會棧溢位

(2)支援很多層級的資料

 function copyObject(orig) {
    var copy = Object.create(Object.getPrototypeOf(orig));
    copyOwnPropertiesFrom(copy, orig);
    return copy;
  }


  function copyOwnPropertiesFrom(target, source) {
    Object
    .getOwnPropertyNames(source)
    .forEach(function (propKey) {
      var desc = Object.getOwnPropertyDescriptor(source, propKey);
      Object.defineProperty(target, propKey, desc);
    });
    return target;
  }

  var obj = {
    name: 'Jack',
    age: '32',
    job: 'developer'
  };

  var obj2 = copyObject(obj);
  console.log(obj2);
  obj.age = 39;
  obj.name = 'Tom';
  console.log(obj);
  console.log(obj2);



分類:JavaScript