-
[JavaScript] 기본형 vs 참조형 / call by value / 깊은 복사 vs 얕은 복사JavaScript 2022. 11. 19. 17:10
1. 기본형 데이터와 참조형 데이터
자바스크립트 데이터 타입은 크게 두가지인 원시형(Primitive Type)과 참조형(Reference Type)으로 분리된다. 기본(원시)형에는 Number, String, Boolean, null, undefined 가 있으며 ES6 에서는 Symbol 도 추가되었다고 한다. 참조형은 대표적으로 객체(Object)가 있고 그 하위에 배열(Array), 함수(Function), 정규표현식(RegExp) 등이 있다. 두 타입의 가장 대표적인 차이로는 기본형에는 바로 값을 그대로 할당한다는 것이고 참조형에는 값이 저장된 주소값을 할당(참조)한다는 것이다.
2. call by value
자바스크립트의 특징인 call by value는 함수 호출 시 arguments로 값이 넘어올 때 복사된 값이 넘어 온다는 것이다. 호출 시 인자를 복사해서 넘겨줬으므로 호출 된 값에 대해 변경사항이 있어도 실제로 반영되지 않는다.
var a = 1; var func = function(b) { // callee b = b + 1; } func(a); // caller console.log(a); // 1
한편 call by reference의 경우는 좀 다른데, 이 경우에는 arguments로 reference(값에 대한 참조 주소, 메모리 주소를 담고있는 변수)를 넘겨주기 때문에 복사하지 않고 넘기는 것을 의미한다. 복사하지 않았기 때문에 호출당한 값을 변경시키면 실제로 변경된다. 그런데 한가지 유의해야할 것이 자바스크립트는 참조 타입을 arguments로 넘겨주면 call by reference의 형태로 작동한다고 잘못 알고있으면 안된다는 것이다. 자바스크립트에서는 무조건 call by value로 작동하기 때문이다. 자바스크립트에서는 참조 타입을 인자로 넘기면 마찬가지로 참조값에 대한 복사본을 만들어서 넘긴다.
var a = {}; var func = function(b) { // callee b = 1; } func(a); // caller console.log(a); // {}
cf. parameter(형식 매개변수)는 함수 선언부에 정의되고, arguments(실인자)는 함수 호출부에서 사용된다.
3. 깊은 복사, 얕은 복사
원시값을 복사할 때 그 값은 또 다른 독립적인 메모리 공간에 할당하기 때문에, 복사를 하고 값을 수정해도 기존 원시값을 저장한 변수에는 영향을 끼치지 않는다. 이처럼 실제 값을 복사하는 것을 깊은 복사라고 합니다.
참조값을 복사할 때는 변수가 객체의 참조를 가리키고 있기 때문에 복사된 변수 또한 객체가 저장된 메모리 공간의 참조를 가리키고 있는다. 그래서 복사를 하고 객체를 수정하면 두 변수는 똑같은 참조를 가리키고 있기 때문에 기존 객체를 저장한 변수에 영향을 끼친다. 이처럼 객체의 참조값(주소값)을 복사하는 것을 얕은 복사라고 합니다. 하지만 객체를 복사할 때 = 키워드를 사용해서 복사하면 얕은 복사가 돼서 기존 변수 또한 수정되어서 매우 어이없었던 기억이 있는데 이 때문이었다.
앝은 복사를 하기 위해서는 Array.prototype.slice() 혹은 Object.assign() 방법을 쓰면 된다고 참고한 게시물에 나와있다.
깊은 복사를 하기위해선 먼저 JSON.stringify()을 사용하여 객체를 json 문자열로 변환하는데 이 과정에서 원본 객체와의 참조가 모두 끊어지게 된다. 이후 JSON.parse()를 이용해 다시 원래 객체로 만들어준다. 처음에 니꼴라스가 저걸 왜 쓰나 했는데 이제야 깨달았다. 또한 개인적인 생각으로 파괴적 처리를 하는 메소드들을 사용할 때, 원본과 파괴적 처리 후의 값을 따로 분리해야할 필요가 있을 때 깊은 복사를 하는 것이 좋을 것 같다.
'JavaScript' 카테고리의 다른 글
Hoisting과 TDZ (0) 2023.02.23 [JavaScript] 유사배열과 배열의 차이는 무엇일까? (0) 2022.11.28 [JavaScript] JavaScript의 자료형과 JavaScript만의 특성은 무엇일까 ? (2) 2022.11.18 [JavaScript] 콜백 함수, 화살표 함수, 타이머 함수 (0) 2022.11.12 [JavaScript] 함수 (익명 함수vs선언적 함수, 나머지 매개변수, 전개 연산자, 기본 매개변수) (0) 2022.11.11