[javascript] primitive type & reference type

viram·2022년 11월 29일
0

C언어의 변수

  • 메모리 주소와 변수가 헷갈릴 때 가장 먼저 떠올리기 쉬운건 메모리 방면에서 가장 프로그래머가 개입할가능성이 많은 C언어이다. C언어는 대표적으로 참조타입(Reference Type)이 없는 언어다. 변수를 정직하게 메모리에 담고 그 메모리를 가르키는 포인터를 지정할 수 있다. 그렇기에 참조타입이 필요가 없거나 무슨 변수를 참조할 것인지 직접 설계할 수 있다. 즉 관념적으로(Conceptually) 포인터를 사용해 참조타입처럼 쓸 수 있으나 문법적으로(Syntactically)는 참조타입이 없다.
  • 다시 말해서, C는 메모리라는 그릇에 변수 내용을 담는 것아, 만일 변수의 내용이 변한다면 그 메모리에 직접 접근에 그 메모리 안에 들어있는 비트수를 바꾼다.
int a = 3;
int b = a;
printf("%x\n", &a);
printf("%x", &b);
//reulst : 94349360 / 94349364
  • 또한 위와 같이, 같은 값이 할당되더라도 b전용으로 메모리 공간을 따로 할당해 그곳에 3이라는 숫자를 넣는다.
    • 이에 반해 참조타입이란, 변수의 내용이 바뀌면 그 바뀐 내용에 대한 메모리 공간을 새로 할당하고 거기에 바뀐 내용을 넣은 다음 이전에 가리키던 메모리 포인터를 새로 할당한 공간으로 바꾸는 것이다.
  • 흔히들 원시값은 단순한 데이터이고 참조값은 메모리에 선언되는 값이라고들 말한다. 하지만 컴퓨터의 구조를 생각해보면, 모든 값은 메모리 위에 선언된다. 또한 C에서 선언되는 변수들은 모조리 Primitive Type이지만 메모리 위에 존재하며 포인터로 접근할 수 있다. 내 생각에 자바스크립트 등 메모리 접근을 불허하는 언어에서 메모리에 선언된 객체에 접근하려면 참조값을 사용해야만 하기 때문에 그런 오해가 생긴 것 같다.
  • 나는 참조 타입을 배울 때 자바에서 제일 먼저 배웠던 것 같다. 자바와 C++등 보편적인 언어에서 &기호를 사용해 참조 타입을 지원하므로 이미 많은 개발자들에게 익숙할 것이다.

자바스크립트는…

원시값

  • copy-by-value
  • 자바스크립트에서 string , number , boolean 등 우리가 생각하는 단순한 변수들은 대부분 원시타입에 해당된다. 간단히 말해서,
c=23;
d=c;
d=4;
console.log(c);
console.log(d);
//result : c = 23, d= 4
  • 이렇게 c를 설정하고 d에 c값을 가져와도 d에 무슨짓을 하던 c를 바꾸지는 않는다는 뜻이다.
  • 그런데 내부 동작원리는 c와 조금 다르다. d가 다시 23이라는 값을 받으면 갑자기 메모리 주소가 같아진다. 즉 자바스크립트 원시값은 한 원시값 변수에 대해 변하지 않는 메모리 위치를 가지고 있다.
    • 이를 불변성(Immunability)라고 한다. 이는 디버깅을 쉽게 하기 위해서, 또 잠재적인 버그를 줄이기 위해서 만들어졌다. 변수가 가리키고 있는 메모리 주소가 달라지지 않는한, 해당변수에게 의도하지 않은 변화가 이루어지지 않는다. 사람이 작성하는 프로그램에는 버그가 있을수밖에 없어서, 해당 변수가 메모리 주소를 잘 잡고 있더라도 다른 메소드가 해당 메모리에 접근해 값을 바꿔버리면 변수 입장에서는 아무것도 할 수 없다. 이에 자바스크립트는 ‘이 메모리만 잘 지키고 있으면 변수가 의도하지 않았는데 변하는 일은 없을 것이다’라는 보장을 주는 것이다.
    • 참고로 상수 const 는 변수의 재할당이 금지된 것을 의미하며 원시값이 불변성을 가지는 것과는 의미가 다르다.
  • 참고로 자바스크립트에서 변수의 메모리 주소를 실제로 확인하기는 매우 어렵다.
  • 참고로 === 3중 equal mark는 strict equl이라는 뜻으로, 두 값의 내용은 물론이고 type까지 같은지 검사하는 것이다. ES2015에서는 3중 equal을 사용할 것을 권장하고 있다.

참조값

  • copy-by-reference
  • 참조값은 우리가 생각하는 대부분의 객체와 배열이다.
let tempMovingItem;
const movingItem = {
  type: "tree",
  top: 0
};

function init() {
  //tempMovingItem = {...movingItem};
  tempMovingItem = movingItem;
  tempMovingItem.top = 4;
  console.log(movingItem);
 }
  
 init(); 
  • tempMovingItem = movingItem; 을 실행하면 movingItem에 top이 4로 찍혀 나온다. 4를 설정한 건 tempMovingItem.top인데 어째서일까? 이는 할당시에 값을 할당한 게 아니라 메모리 주소를 할당했기 때문이다. Shallow Copy라고도 한다.
  • 객체와 배열에는 불변성이 없다. 값이 변해도 이들을 가리키는 메모리 주소는 변하지 않는다. Mutable Type이라고 한다.
  • 만약 객체를 복사해서 할당할 때 메모리 값이 아니라 내용을 deep copy하고 새로운 메모리 주소를 할당하고 싶으면 tempMovingItem = {…movingItem}; 이라고 하면 된다. … 문법은 객체에 속한 값만 들고 온다는 뜻이다.

참고자료
https://dzone.com/articles/do-you-really-need-immutable-data
https://sustainable-dev.tistory.com/156
https://velog.io/@1000nion/원시값과-참조값
https://stackoverflow.com/questions/4305673/does-c-have-references
https://velog.io/@josuncom/JavaScript-원시값과-참조값

profile
취미로 번역하고 직업으로 개발합니다

0개의 댓글