[Javscript] 얕은 복사 / 깊은 복사

study 04.

얕은 복사와 깊은복사

  • 얕은 복사(shallow copy)는 바로 아래 단계의 값만 복사하는 방법이고, 깊은 복사(deep copy)는 내부의 모든 값들을 하나하나 찾아서 전부 복사하는 방법이다.

원시값 (primitive value)

  • 원시값은 값은 복사할 때 복사된 값을 다른 메모리에 할당하기 때문에 원래의 값과 복사된 값이 서로에게 영향을 미치지 않는다.

     ex) string, number, boolean, null, undefined
var a = 1;
var b = a;

b = 2

console.log(a); //1
console.log(b); //2

참조값 (reference value)

  • 변수가 객체의 주소를 가리키는 값이기 때문에 복사된 값(주소)이 같은 값을 가리킨다.

     ex) object
var a = {number: 1};
var b = a;

b.number = 2

console.log(a) //{number: 2}
console.log(b) //{number: 2}

얕은 복사

  • 중첩된 객체에서 참조형 데이터가 저장된 프로퍼티를 복사할 때 그 주소값만 복사한다.
  • user 객체에 직접 속한 프로퍼티에 대해서는 복사해서 완전히 새로운 데이터가 만들어지는 반면, urls의 네부 프로퍼티들은 기존 데이터를 그대로 참조한다.
var user = {
  name:"Jaenam",
  urls: {
    portfolio:"http://github.com/abc",
    blog:"http://blog.com",
    facebook:"http://facebook.com/abc"
  }
};

// 기존 정보를 복사해서 새로운 객체를 반환하는 함수(얕은 복사만 수행)
var copyObject = function(target) {
  var result = {};
  for(var prop in target) {
    result[prop] = target[prop];
  }
  return result;
}

var user2 = copyObject(user);

user2.name = "Jung";
console.log(user.name === user2.name);            // false

user.urls.portfolio = "http://portfolio.com";
console.log(user.urls.portfolio === user2.urls.portfolio);       // true

user2.urls.blog = "";
console.log(user.urls.blog === user2.urls.blog);                 // true

깊은 복사

  • 객체의 프로퍼티 중에서 그 값이 기본형 데이터일 경우에는 그대로 복사하면 되지만 참조형 데이터는 다시 그 내부의 프로퍼티들을 복사해야 한다.
  • 프로퍼티의 내부까지 복사해서 새로운 데이터를 만든다.
var user2 = copyObject(user);
user2.urls = copyObject(user.urls);

user.urls.portfolio = "http://portfolio.com";
console.log(user.urls.portfolio === user2.urls.portfolio); // false

user2.urls.blog = "";
console.log(user.urls.blog === user2.urls.blog);      // flase

깊은 복사 방법

1. 객체의 깊은 복사를 수행하는 함수

var copyObjectDeep = function(target){
	var result = {};
	
	if(typeof target === "object" && target !== null){
		for (var prop in target){
			result[prop] = copyObjectDeep(target[prop]);
		}
	}	else {
		result = target;
	}
	retrun result;
}

1-1. 깊은 복사 결과

var obj = {
	a : 1,
  b : {
		c : null,
		d : [1, 2]
	}
};

var obj2 = copyObjectDeep(obj);

obj2.a = 3;
obj2.b.c = 4;
obj2.b.d[1] = 3;

console.log(obj);    // { a : 1, b : { c : null, d : [1, 3] } }
console.log(obj2);   // { a : 3, b : { c : 4,    d : { 0 : 1, 1 : 2 }} }

2. JSON 을 활용한 깊은 복사

  • httpRequest 로 받은 데이터를 저장한 객체를 복사할 때 등 순수한 정보만 다룰 때 활용하기 좋은 방법이다.
var obj = {
  a: 1,
  b: {
    c: 2,
  },
};

var copyObjectJSON = JSON.parse(JSON.stringify(obj));
//string(원시값)으로 변환 후 다시 객체로 만들어 주었다. => 원래값과 복사값이 서로 영향을 받지 않는다.

copyObjectJSON.b.c = 3
console.log(obj.b.c)        //2
console.log(copyObjectJSON.b.c)    //3

obj.b.c === copyObjectJSON.b.c    //false

3. 라이브러리(lodash)


var obj = {
  a: 1,
  b: {
    c: 2,
  },
};

var copyObj = _.cloneDepp(obj);

copyObj.b.c = 3;

obj.b.c === copyObj.b.c     //false

좋은 웹페이지 즐겨찾기