[전단 면접] 깊이 있게 복사하는 방법, 손으로 깊이 복사하는 함수

24683 단어 면접 시험
본고의 내용: 1. 세 가지 방법으로 대상의 얕은 복사를 실현한다. 2. 두 가지 방법으로 대상의 깊은 복사를 실현한다. 3. 간단한 깊은 복사 함수를 실현한다.

얕은 복사


방법1: Object.assign()


배열
let arr = [1, 2, 3, [10, 20, 30]];
let newArr = Object.assign(arr);

newArr[3][0] = 100;

console.log(arr);
console.log(newArr);

// [ 1, 2, 3, [ 100, 20, 30 ] ]
// [ 1, 2, 3, [ 100, 20, 30 ] ]

대상
let obj = { a: 1, b: 2, c: { m: 10, n: 20 } }
let newObj = Object.assign(obj);

newObj.c.m = 100;

console.log(obj);
console.log(newObj);

// { a: 1, b: 2, c: { m: 100, n: 20 } }
// { a: 1, b: 2, c: { m: 100, n: 20 } }

메서드 2: 확장 연산자


배열
let arr = [1, 2, 3, [10, 20, 30]];
let newArr = [...arr];

newArr[3][0] = 100;

console.log(arr);
console.log(newArr);

// [ 1, 2, 3, [ 100, 20, 30 ] ]
// [ 1, 2, 3, [ 100, 20, 30 ] ]

대상
let obj = { a: 1, b: 2, c: { m: 10, n: 20 } }
let newObj = { ...obj };

newObj.c.m = 100;

console.log(obj);
console.log(newObj);

// { a: 1, b: 2, c: { m: 100, n: 20 } }
// { a: 1, b: 2, c: { m: 100, n: 20 } }

방법 3: 옮겨다니기


배열
let arr = [1, 2, 3, [10, 20, 30]];
let newArr = [];
arr.forEach((item) => {
  newArr.push(item);
})

newArr[3][0] = 100;

console.log(arr);
console.log(newArr);

// [ 1, 2, 3, [ 100, 20, 30 ] ]
// [ 1, 2, 3, [ 100, 20, 30 ] ]

대상
let obj = { a: 1, b: 2, c: { m: 10, n: 20 } }
let newObj = {};
for(let key in obj){
  newObj[key] = obj[key];
}

newObj.c.m = 100;

console.log(obj);
console.log(newObj);

// { a: 1, b: 2, c: { m: 100, n: 20 } }
// { a: 1, b: 2, c: { m: 100, n: 20 } }

딥 카피


방법1:lodash 플러그인에서cloneDeep()

const _ = require("lodash");

let arr = [1, 2, 3, [10, 20, 30]];
let newArr = _.cloneDeep(arr);

newArr[3][0] = 100;

console.log(arr);
console.log(newArr);

// [ 1, 2, 3, [ 10, 20, 30 ] ]
// [ 1, 2, 3, [ 100, 20, 30 ] ]

방법2: JSON.parse() + JSON.stringify()

let arr = [1, 2, 3, [10, 20, 30]];
let newArr = JSON.parse(JSON.stringify(arr));

newArr[3][0] = 100;

console.log(arr);
console.log(newArr);

// [ 1, 2, 3, [ 10, 20, 30 ] ]
// [ 1, 2, 3, [ 100, 20, 30 ] ]

국한은 undefined를 무시하고 symbol은 서열화 함수를 무시하며 순환 인용 대상을 해결하지 못합니다

손으로 쓴 간단한 심도 복사 함수

function deepClone(obj) {
  function isObject(para) {
    return (typeof para === "object" || typeof para === "function") && para !== null;
  }

  if (!isObject(obj)) {
    return obj;
  }
  let cloneObj = Array.isArray(obj) ? [] : {};
  for (let key in obj) {
    if (obj.hasOwnProperty(key)) {
      cloneObj[key] = isObject(obj[key]) ? deepClone(obj[key]) : obj[key];
    }
  }
  return cloneObj;
}


let arr = [1, 2, 3, [10, 20, 30]];
let newArr = deepClone(arr);
newArr[3][0] = 100;
console.log(arr);
console.log(newArr);
// [ 1, 2, 3, [ 10, 20, 30 ] ]
// [ 1, 2, 3, [ 100, 20, 30 ] ]


let obj = { a: 1, b: 2, c: { m: 10, n: 20 } }
let newObj = deepClone(obj);
newObj.c.m = 100;
console.log(obj);
console.log(newObj);
// { a: 1, b: 2, c: { m: 10, n: 20 } }
// { a: 1, b: 2, c: { m: 100, n: 20 } }

사고의 방향
  • 전송된 파라미터가 인지 판단하고 일 경우 전송된 파라미터를 직접 되돌려준다.
  • 전송된 파라미터가 인지 인지 판단하여 각각 대응하는 구조를 초기화한다.
  • for in를 사용하여 대상을 훑어보고 이 속성이 대상의 자체 속성인지 아닌지obj.hasOwnProperty(key)를 판단한다.
  • 대응하는 속성 값이 인지 판단하고 데이터 형식을 인용하면 이 함수를 호출하고 그렇지 않으면 초기화된 구조에 직접 추가한다.
  • 좋은 웹페이지 즐겨찾기