[Study/JavaScript] 기본형 vs. 참조형 / 참조형 복사하기

SoShy·2023년 11월 30일

JavaScript_Study

목록 보기
16/36
post-thumbnail

🥕 기본형 vs. 참조형



let x = {name: 'Codeit'};
let y = x;

console.log(x);
console.log(y);

y.birth = 2017;

console.log(x);
console.log(y);

위 코드를 실행하면, console.log(x)console.log(y)의 결과값이 다르게 나와야 할 것 같지만,

실제로는, 아래와 같이, 동일한 결과값이 출력되는 것을 확인할 수 있음. 🤔

>>> { name: 'Codeit' }
	{ name: 'Codeit' }
	{ name: 'Codeit', birth: 2017 }
	{ name: 'Codeit', birth: 2017 }

그 이유는, JS에서 변수에 객체 값을 할당하는 경우에는, 객체 값이 어딘가에서 만들어지고, 변수에는 그 객체 값으로 가는 주소가 할당되기 때문...

위 그림과 같이, 변수 x에는 객체로 가는 길이 열려있는 것이기 때문에, x가 할당된 y 역시, 같은 객체로 가는 길이 열릴 수 있는 것

배열도 객체이기 때문에, 위와 동작원리 동일함.

let x = [1, 2, 3];
let y = x;

console.log(x);
console.log(y);

y[2] = 4;

console.log(x);
console.log(y);
.
.
.
>>> [1, 2, 3]
	[1, 2, 3]
	[1, 2, 4]
	[1, 2, 4]


🥕 참조형 복사하기

배열은 아래와 같이, slice를 이용해서 간단하게 해결 가능

let numbers1 = [1, 2, 3];
let numbers2 = numbers1.slice();

numbers2.push(4);

console.log(numbers1);
console.log(numbers2);
.
.
.
>>> [ 1, 2, 3 ]
	[ 1, 2, 3, 4 ]

객체는 slice method를 사용할 수 없기 때문에, Object.assign를 통해 해결하거나,

let course2 = Object.assign({}, course1);

아래와 같이, 단순하게 for...in 반복문으로 해결할 수 있음.

let course1 = {
  title: '파이썬 프로그래밍 기초',
  language: 'Python'
}

let course2 = {};

for (let key in course1) {
  course2[key] = course1[key];
}

course2.title = '알고리즘의 정석';

console.log(course1);
console.log(course2);
.
.
.
>>> { title: '파이썬 프로그래밍 기초', language: 'Python' }
	{ title: '알고리즘의 정석', language: 'Python' }

이걸 함수를 사용해서 좀 더 효율적으로 바꿔보면,

function cloneObject(object) {
  let temp = {};
  
  for (let key in object) {
    temp[key] = object[key];
  }
  
  return temp;
}

let course1 = {
  title: '파이썬 프로그래밍 기초',
  language: 'Python'
}

let course2 = cloneObject(course1);

course2.title = '알고리즘의 정석';

console.log(course1);
console.log(course2);
.
.
.
>>> { title: '파이썬 프로그래밍 기초', language: 'Python' }
	{ title: '알고리즘의 정석', language: 'Python' }

참조형 복사 시 주의해야 할 점은, 아래와 같이 value배열을 사용하게 되면, 주소값이 또 복사되기 때문에 무용지물이 된다는 것

function cloneObject(object) {
  let temp = {};
  
  for (let key in object) {
    temp[key] = object[key];
  }
  
  return temp;
}

let course1 = {
  title: '파이썬 프로그래밍 기초',
  language: 'Python',
  prerequisite: []
}

let course2 = cloneObject(course1);

course2.title = '알고리즘의 정석';
course2.prerequisite.push('에라 모르겠다');

console.log(course1);
console.log(course2);
.
.
.
>>> {
    title: '파이썬 프로그래밍 기초',
    language: 'Python',
    prerequisite: [ '에라 모르겠다' ]
  }
  { title: '알고리즘의 정석', language: 'Python', prerequisite: [ '에라 모르겠다' ] }

💡 객체의 property나 배열의 요소들이 변경되는 경우는, 변수가 가진 주소값을 변경하는 게 아니기 때문에, const 키워드로 변수를 선언했다고 하더라도, 변수의 값이 변할 수 있음.

profile
프론트엔드 개발자가 되기 위해 노력 중인 새싹🌱 입니다.

0개의 댓글