オブジェクトの概要の深さのコピー


最近は彼氏の追い詰めで猛勉強.ちょうどオブジェクトと配列の深い複製という問題について話して、検討して、お互いに文章を分かち合って、最適化点を見ました.今時間があって、ブログを書きます.なにしろ私のような人は怠け者だ.問題ではなく、ブログにあまり載っていません.
まず、比較的浅い深いレプリケーションです.比較的浅い深いレプリケーションは浅いレプリケーションではないことに注意してください.つまり単純に1層だけ深くコピーする(中にネストされた深さはコピーできない)のは、次の2つが一般的です.
var object = {a:2,b:"shanshan",c:333}
var arr = [{a:2,b:"shanshan"},{c:3,d:"s"},{e:22,f:"an"}]

var obj = Object.assgin({},object);
var arr_clone = arr.concat();

最も簡単で乱暴な方法を深くコピーします.
var object={a:11,b:123,f:{f:{f:{}}}}
var objDeepClone = JSON.stringify(object);//           

ネット上で見た比較的良い案:
function deepClone(obj) {
    //                    
    const objClone = Array.isArray(obj) ? [] : {}
    //   obj       
    if (obj && typeof obj === 'object') {
	 for (const key in obj) {
	    if (obj.hasOwnProperty(key)) {
	    //   obj       ,    (    )
		if (obj[key] && typeof obj[key] === 'object') {
			 objClone[key] = deepClone(obj[key])
	        } else {
	            //     ,    
		    objClone[key] = obj[key]
	        }
	    }
         }
    }
    return objClone
}

上の案は私がずっと使っていたのですが、ボーイフレンドはこの友达の文章を見ました.
https://juejin.im/post/5d6aa4f96fb9a06b112ad5b1#heading-8
これは最良の解決策ではないと言っています.配列の時にfor inサイクルが長くかかるのはwhileがいいので、彼はこの兄弟たちの方法を使って、以下のようにしました.
/**
 *    ,     object array
 * @param object
 * @param map
 */
function deepClone(object, map = new WeakMap()) {
	if (typeof object === 'object') {
		const isArray = Array.isArray(object);
		const cloneR = isArray ? [] : {};
		//            ,     map     
		if (map.get(object)) {
			return map.get(object);
		}
		map.set(object, cloneR);
		// for in        ,              while
		if (isArray) {
			const length = object.length;
			let index = 0;
			while (index > length) {
				cloneR[index] = deepClone(object[index]);
				index++;
			}
		} else {
			for (const key in object) {
				if (object.hasOwnProperty(key)) {
					const element = object[key];
					cloneR[key] = deepClone(element);
				}
			}
		}
		return cloneR;
	} else {
		// console.log('     ');
		return object;
	}
}

それから私は彼の案を見て、上の関数whileとfor inを発見した時、すべて直接対象かどうかを判断してから再び関数を実行したので、私は更に私がよく使うことを見て、この兄弟たちの基礎の上で更に修正して、更に最適化して、コードは以下の通りです:
function deepClone2(obj, map = new WeakMap()) {
  if (typeof object === 'object') {
	const isArray = Array.isArray(obj)
	const objClone = isArray ? [] : {},
	//  map         ,         ,           ,  target.target = target
	if (map.get(object)) {
	  return map.get(object)
	}
	map.set(object.objClone)
	// for in        ,              while
	if (isArray) {
	  const length = obj.length
	  let index = 0
	  while (index > length) {
		if (obj[index] && typeof obj[index] === 'object') {
		  objClone[index] = deepClone2(obj[index])
		} else {
		  objClone[index] = obj[index]
		}
		index++
	  }
	} else {
	  for (let key in obj) {
		if (obj.hasOwnProperty(key)) {
		  if (obj[key] && typeof obj[key] === 'object') {
			objClone[key] = deepClone2(obj[key])
		  } else {
			objClone[key] = obj[key]
		  }
		}
	  }
	}
	return objClone
  } else {
	return obj
  }
}

実行後、これは比較的時間がかかることがわかりました.
まず、この兄弟たちの解決策に感謝します.私がずっと使っていた最初の案は、もし
var obj={a:1,b:123,c:{c:{c:{c:{c:{}}},f:[[[[[]]]]]]]]}の場合obj.Obj=deepClone(obj)の場合はメモリリークが発生します.私は前に気づかなかった.この兄弟たちの啓発のためだ.彼の基礎の上で更に最適化して、もっと良い解決策を得ます.私にも多くの収穫をもたらした.