Javascript 참조 타입의 특성
○ Javascript 기본타입인 숫자 / 문자열 / 불린 / null / undefined를 제외한 모든 값은 객체입니다.
○ 객체의 모든 연산은 실제 값이 아닌 참조값으로 처리합니다.
객체가 갖는 '참조'의 의미는?
아래와 같이, 임의의 객체와 해당 객체의 프로퍼티를 생성하고 대입하는 과정을 살펴보겠습니다.
var newObjA = {
value : 100
};
var newObjB = newObjA;
console.log(newObjA.value);
console.log(newObjB.value);
/* 출력 */
// 100
// 100
새로운 객체 newObjA에 프로퍼티 value를 선언해 두었습니다. 그리고 newObjB에 newObjA 객체 자체를 대입시켜 두었습니다. 중요한 것은, newObjA의 경우 변수 자체가 프로퍼티와 값을 직접 저장하고 있지 않습니다.
newObjA라는 변수는 새로 생성된 객체를 가리키는 참조값만을 갖고 있습니다. 쉽게 말하면 참조값의 메모리 주소를 저장하게 되는 관념이라고 이해하시면 됩니다. 특히, newObjB에 newObjA 객체 자체를 할당하였는데 이 동작은 객체를 복사하거나 값을 대입하는 과정이 아닙니다. 이 역시, newObjA가 갖고있는 참조값을 newObjB에 할당한다는 의미입니다.
그렇기 때문에, newObjA와 newObjB가 갖는 프로퍼티 value를 각각 출력하면 동일한 값이 출력됩니다. 이 시점에 value 프로퍼티 값을 수정하면 어떤 결과가 나오는지 확인해 봅시다.
newObjB.value = 999;
console.log(newObjA.value);
console.log(newObjB.value);
/* 출력 */
// 999
// 999
위에서 newObjB의 value 값을 999로 갱신하였습니다. 그리고 newObjA와 newObjB가 가진 value를 출력하였더니, 갱신한 값 999로 모두 바뀌었습니다. 결과적으로 아래와 같은 구조의 참조 구조를 갖고 있다는 것을 확인할 수 있습니다.
○ 각각의 변수(newObjA / newObjB)는 객체가 가진 값을 참조하는 구조입니다.
○ 객체의 값 자체를 변경하게 되면, 변수가 바라보는 값이 변경되기 때문에 출력값이 동일하게 변경됩니다.
'비교'를 통한 객체의 특성 알아보기
우선 기본 데이터 타입으로 값을 비교해 보도록 합시다.
var testA = 100;
var testB = 100;
console.log(testA == testB);
/* 출력 */
// true
위의 경우, 기본 타입인 변수 두 개가 같은 값을 가지고 있습니다. 그리고 두 변수를 비교해 보면 값 자체를 비교합니다. 그렇기 때문에 true가 출력됩니다.
이번에는 두 개의 객체를 비교해 봅시다.
var newObjA = { value : 999 };
var newObjB = { value : 999 };
console.log(newObjA == newObjB);
/* 출력 */
// false
프로퍼티 형태와 값이 동일한 두 객체인 newObjA와 newObjB를 비교했습니다. 그리고 출력되는 값은 false로 확인됩니다. 두 개의 변수는 객체이므로 위에서 설명했던 것 처럼, 두 개의 변수는 객체에 대한 참조값만을 갖고 있습니다. 그래서 두 변수의 참조 관계는 아래와 같은 상황입니다.
그래서 비교했을 때 false가 출력됩니다. 기본 타입과 참조 타입의 차이점이 여기서 극명하게 드러납니다. 그럼, 여기서 객체간의 참조를 수행하고 다시 비교를 진행해 봅시다.
var newObjC = newObjB;
console.log(newObjB == newObjC);
/* 출력 */
// true
위의 경우에는 true가 출력됩니다. newObjB와 newObjC는 같은 객체를 참조하는 변수가 되었기 때문에, 비교할 경우 true가 출력되는 것입니다. 이 구조를 그림으로 나타내면 아래와 같습니다.
Call by Value vs. Call by Reference
함수를 호출하면서 이 과정에서 전달되는 인자값의 경우에도, 기본 타입과 참조 타입에서 차이가 발생합니다. 아래와 같이 함수 testFunc에 기존 데이터 타입 / 참조 타입 인자를 각각 전달해 값을 변경해 보겠습니다.
var newVal = 999;
var newObjA = { value: 999 };
function testFunc(val, obj) {
val = 1;
obj.value = 1;
console.log(val);
console.log(obj);
}
testFunc(newVal, newObjA);
console.log(newVal);
console.log(newObjA);
/* 출력 */
// 1
// { value: 1 }
// 999
// { value: 1 }
이 경우, testFunc에 인자로 전달된 newVal은 기본 타입의 데이터이기 때문에 값인 '999'가 복사되어 전달됩니다. 그래서 함수 testFunc 내부에서 출력했을 때는 1로 출력되지만, 함수 외부에서 newVal을 출력하면 본래의 값 999로 출력됩니다.
하지만 newObjA가 testFunc함수에 인자로 전달하게 되면 값이 복사되는 것이 아니며, 객체의 참조값이 전달됩니다. 그래서 testFunc 내부에서 해당 값을 변경하였을 때 해당 값은 그대로 반영이 됩니다.
'Programming > Javascript' 카테고리의 다른 글
5. Javascript 배열 (1) - 배열의 특성 (0) | 2022.08.23 |
---|---|
4. Javascript 프로토타입([[Prototype]]) (0) | 2022.08.19 |
2. Javascript 참조 타입 (2) - 객체 프로퍼티 읽고, 쓰고, 삭제하기 (0) | 2022.08.18 |
2. Javascript 참조 타입 (1) - 객체 생성 (0) | 2022.08.14 |
1. Javascript 기본 데이터 타입(2) (0) | 2022.08.09 |