Primitive type vs Object type

Primitive type과 Object type

Javascript의 데이터 타입은 7가지이다.
이 중 Object를 제외한 6가지는 원시타입(primitive type)이다.
데이터 타입을 원시타입과 객체타입으로 나누는 가장 큰 차이는 세가지가 있다.

  • 원시타입의 값은 immutable로 변경이 불가능하다.
  • 원시 값을 변수에 할당하면 변수에는 실제 값이 저장된다. 하지만 객체를 변수에 할당하면 변수에는 참조 값이 저장된다.
  • 원시 값을 갖는 변수를 다른 변수에 할당하면 값이 복사되어 전달된다. 하지만 객체를 가리키는 변수를 다른 변수에 할당하면 원본의 참조 값이 복사되어 전달된다.

원시값

immutable

한번 생성된 원시 값은 read only이다.
즉 변경이 불가능하다.
여기서 변경이 불가능 하다는 것은 변수가 아니라 값 자체이다.
변수의 값을 바꾸는 것은 재할당이다.
변수는 새로운 값을 재할당하여 값을 바꿀 수 있다. 그렇기에 변수이다.
재할당을 할 수 없는 것은 상수이지만 상수역시 변수다.
원시값의 변경 불가능은 상수가 갖는 재할당을 못한다는 것과는 다른 것이다.

원시 값을 갖는 변수에 재할당을 하면 값이 바뀌는 것이 아니라 변수가 참조하고 있던 메모리 공간의 주소가 바뀌는 것이다.

즉, 이전의 값은 변경을 할 수 없는 변경 불가능이기 때문에 새로운 메모리 공간에 새로운 값을 저장하고 그 새로운 공간의 주소를 변수가 참조하는 것이다.

상수는 이 새로운 공간에 대한 참조를 막아 한 번만 참조를 하고 다시는 참조하지 못하도록 재할당을 막는 것이다.

원시타입을 갖는 변수에 값을 바꾼다는 것은 원시타입의 값이 바뀌는 것이 아니라 변수가 다른 값을 갖는 공간을 참조하는 것이다.

String타입역시 원시값으로 변경 불가능이다.
그러나 유사배열인 String타입의 변수에 index를 이용하여 값을 변경시키려고 하면 오류가 발생하지 않는다.
그러나 String은 변경 불가능으로 다시 원래의 변수의 값을 확인하면 바뀌지 않는다.

Pass by Value or Call by Value

어떠한 변수에 원시값을 할당한다.
그리고 또 다른 변수에 앞의 변수를 할당한다.
그렇면 두 변수의 값은 동일하다.
그러나 하나의 변수에 다른 값을 다시 할당한다고 해서 다른 변수의 값이 바뀌지 않는다.

이는 두 변수가 값은 같지만 서로 다른 메모리 공간을 바인딩 하였기 때문이다.

두번째 변수에 첫번째 변수를 할당하면 값은 갖지만 그것은 할당되는 변수의 값을 복사하여 할당받는 할당한 것이기 때문이다.

이것은 함수나 메서드의 파라미터에 값을 전달할 때 역시 마찬가지다

그렇기 때문에 파라미터로 받은 값을 변경한다고 하여도 함수를 호출한 곳의 아규먼트의 값은 바뀌지 않는다.

이것을 값에 의한 전달 혹은 값에 의한 호출이라고 한다.

객체

객체는 프로퍼티를 갖는데 이 프로퍼티의 개수가 정해져 있지 않고 동적으로 추가하고 삭제할 수 있다.
그렇기 때문에 확보해야 할 공간의 크기를 미리 정할 수 없다.

그렇기 때문에 원시값과는 다른 동작을 한다.

mutable

원시값을 변수에 할당하면 변수는 원시값이 저장되어 있는 메모리 공간에 바인딩된다.

그리고 변경 불가능하기 때문에 새로운 값을 할당하면 변수는 새로운 메모리 공간에 바인딩된다.

하지만 객체는 객체가 실제 저장되어 있는 공간에 변수가 바인딩되는 것이 아니라 실제 저장되어 있는 메모리 공간의 주소를 가지고 있는 메모리 공간에 바인딩된다.

즉, 객체가 가지고 있는 프로퍼티의 값을 변경하면 객체변수의 메모리 공간이 원시타입처럼 바뀌는 것이 아니라 값이 실제 저장되어 있는 공간에서 해당 프로퍼티가 변경이 되는 것이다.

그렇기 때문에 객체타입의 변수는 여전히 같은 공간에 바인딩 되어 있지만 값이 변하는 것이다.

즉 실제 값이 저장되어 있는 곳이 바뀌더라도 여전히 객체는 주소를 가지고 있고 그 주소는 변하지 않기 때문에 메모리 공간의 교체 없이 값을 바꿀 수 있다.

얇은 복사와 깊은 복사

원시타입의 값은 복사를 하면 값 자체가 복사가 되기 때문에 원본 값을 바꾼다고 하여도 복사된 값이 바뀌지 않는다.

하지만 객체는 객체 자체가 복사되는 것이 아니라 그 객체가 존재하는 메모리 공간의 주소가 값으로 복사되기 때문에 원본과 복사본 모두 동일한 메모리 공간의 주소를 갖고 그 주소의 값을 이용하기 때문에 둘 중하나의 객체의 프로퍼티를 수정하면 두 변수의 값 모두 변경된다.

이런 복사를 얇은 복사라고 하며 두 변수가 서로 독립적인 객체를 갖도록 하는 것 깊은 복사이다.

Pass by reference or Call by reference

객체 타입의 변수를 다른 변수에 할당하면 두 변수는 동일한 값을 갖는 얇은 복사가 일어난다.

이것은 원본 변수가 가지고 있는 것이 객체가 아니라 그 객체의 주소이기 때문에 주소가 복사되어 결국 두 변수 모두 같은 주소를 저장하고 있기 때문에 객체 자체는 같은 객체를 공유하는 것이기 때문이다.

이처럼 객체는 값이 아니라 값을 가지고 있는 메모리 공간의 주소를 참조하는 형식이며 이 참조값이 주소가 전달되는 것이다.

그래서 파라미터로 객체를 주면 해당 객체의 주소가 복사되고 그 객체의 프로퍼티를 바꾼다 하여도 주소는 바꾸지 않고 참조되고 있는 객체의 값은 양쪽 모두가 변경된다.

이렇게 참조에 의해 값이 전달되는 것을 참조의 의한 전달이라고 한다.

사실 엄밀히 말하면 주소값도 값으로 Pass by Value이지만 그냥 Pass by reference라 하자

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×