본문 바로가기

JavaScript/JS 기초

JavaScript 원시 타입과 객체 타입, 원시 값과 객체




원시 타입과 객체 타입, 원시 값과 객체

자바스크립트는 7가지 데이터 타입을 제공한다. 데이터 타입은 숫자, 문자열, 불리언, null, undefined, 심벌, 객체 타입이 있다. 이걸 크게 분류하면 원시 타입객체 타입으로 나눌 수 있다. 이렇게 나누는 이유는 많이 다르기 때문이겠지?

-원시 타입의 값은 변경 불가능한 값immutable value인데 객체 타입은 변경 가능한 값이다.mutable value
-원시 값을 변수에 할당하면 변수에는 실제 값이 저장된다. 이는 메모리에 실제 값이 저장된다는 의미이다.
하지만 객체는 변수에 값을 할당하면 변수에 참조 값이 저장된다. 이는 메모리에 참조 값이 저장된다는 말이다.
-원시 값을 갖고 있는 변수를 다른 변수에 할당하면 원본의 값이 복사되어서 전달된다. 이를 값에 의한 전달pass by value라고 부르고, 객체는 참조 값이 복사된다. 이를 참조에 의한 전달pass by reference이라고 부른다.

원시 값

변경 불가능하다.


원시 타입의 값은 변경 불가능하다. 읽기 전용 값이라고 볼 수도 있다. 원시 값은 어떤 일이 있어도 불변한다. 이러한 원시 값의 특성은 데이터의 신뢰성을 보장해준다.

예를 들어보자. 변수를 선언(var score;)를 하면 메모리 참조 101번지에 undefined로 값이 할당된다. 변수에 값을 할당하면?(score = 80;) 그러면 메모리 참조 103번지에 새롭게 80이라는 값을 담게 된다. 값을 재할당 하게 되면(score = 90;) 메모리 참조 106번지에 90을 넣어서 참조하게 된다. 변수에 할당된 원시 값이 변경 불가능하기 때문이다.

문자열


문자열도 원시 타입으로 값을 변경할 수 없다. 문자열 중 한 문자를 변경해보려고 한다. 문자열은 유사 배열 객체array-like object이다. 유사 배열 객체란 건 배열과 비슷하단 말이다. 배열처럼 인덱스로 프로퍼티 값에 접근할 수도 있고. length 프로퍼티도 갖고 있다.

var str = 'string';
str[0] = 'S' //array-like object 유사 배열 객체여서 문자에 접근할 수 있다.

console.log(str);

위 코드는 String이 아닌 string이 찍힌다. 이미 생성된 문자열의 일부 문자를 변경하려고 해도 바꿀 수 없다. 문자열은 변경 불가능한 값이기 때문이다.

값에 의한 전달


var score = 80;
var copy = score;

console.log(score); // 80
console.log(copy); // 80

score = 100;

console.log(score); // 100
console.log(copy); // 80

원시 값을 갖고 있는 변수를 다른 변수에 할당하면 원본의 값이 복사되어서 전달된다. 값에 의한 전달pass by value라고 부른다.

score 변수와 copy 변수의 값은 다른 메모리 공간에 저장된 별개의 값이라고 보면 된다. score값을 변경해도 copy 변수의 값에는 어떤 영향도 없다.

객체

*자바나 C++ 같은 클래스 기반 객체지향 프로그래밍 언어는 사전에 정의된 클래스를 기반으로 객체를 생성한다. 이건 객체 생성하기 전에 이미 프로퍼티와 메서드가 정해져있다는 말이고, 그대로 객체를 생성하게 된다. 그리고 생성 이후에는 프로퍼티를 삭제하거나 추가할 수 없다. 하지만 자바스크립트는 조금 다르다. 자바스크립트는 클래스 없이 객체를 생성하고, 생성 이후에도 프로퍼티와 메서드를 추가하거나 삭제할 수 있다. 사용에는 편리하지만 생성 이후에도 프로퍼티 접근이 이루어지니 비효율적인 면이 있다. 그래서 V8 자바스크립트 엔진에서는 동적 탐색, 히든 클래스 라는 방식을 통해 성능을 보장하고 있다.

변경 가능하다


객체 타입은 변경 가능하다. 객체를 할당한 변수는 메모리에 주소 값을 저장한다. 이 주소 값을 따라가면 또 다른 메모리 공간에 접근할 수 있다. 여기에 바로 객체가 저장되어있다.(참조 값reference value라고 부른다)

var person = {
  name: 'Lee'
};

console.log(person); // {name: "Lee"}

console.log(person);을 하게 되면 메모리 person 주소 101번으로 간다. 갔더니 104번 주소를 참조하고 있더라. 그래서 104번으로 가서 참조 값을 가지고 와서 뿌려준다.

pserson.name = 'Kim';
person.number = '0615';

console.log(person); // {name: "Kim", number: "0615"}

객체는 변경 가능하다. 객체는 재할당 없이 값을 변경할 수 있다. 객체는 많은 프로퍼티를 가질 수 있다. 생성하고 관리하는데도 많은 메모리 자원이 든다. 만약 객체의 내용을 한 두개 변경할 때 마다 새롭게 만들어서 쓰면? 성능면에서 효율이 아주 떨어질 것이다. 그래서 객체는 변경 가능한 값으로 설계되어 있다. 데이터의 신뢰성은 좀 떨어지지만 전략적인 선택이라고 볼 수 있다.

참조에 의한 전달


객체는 참조 값을 저장하고 있다. 그 말은 변수에 담긴 값을 복사했을 때 참조 값이 복사된다는 말이다. 이를 참조에 의한 전달pass by reference라고 부른다.

var person = {
  name: 'Lee'
};

var copy = person;

copy.name = 'Kim';
copy.address = 'Jeju';

console.log(person); // { name: "Kim", address: "Jeju");

여기서 주의해야 할 건 어느 한 변수를 통해 객체의 프로퍼티에 접근해서 값을 변경하면, 복사 된 다른 변수 또한 같은 영향을 받는다는 것이다. 개발할 때 이 점을 잘 생각해서 새로운 객체가 필요하다면 꼭 깊은 복사를 해서 사용하도록 하자.




반응형