[딥다이브] 008. 원시 값과 객체의 비교

1. 원시값과 객체의 차이

  • 변경 가능한가?

    • 원시 값 : 변경 불가능한 값(immutable value)
    • 객체: 변경 가능한 값(mutable value)
  • 변수(확보된 메모리)에 저장되는 값이 무엇인가?

    • 원시 값: 메모리에 실제 값이 저장
    • 객체 값: 메모리에 참조 값이 저장
  • 값을 갖는 변수를 다른 변수에 할당하면 무엇이 복사되는가?

    • 원시값: 원본의 원시 값 (값에 의한 전달)
    • 객체값: 참조값 (참조에 의한 전달)

2. 원시 값

  • 변수와 값
    • 변수는 메모리 공간을 식별하기 위해 붙인 이름
    • 값:변수에 저장된 데이터 (변경 가능)
  • 변수와 상수
    • 변수: 재할당이 가능한 변수
      재할당을 통해 변수 값을 교체
    • 상수: 재할당이 금지된 변수(단, 객체는 변경 가능)
  • 변수 값을 변경하려면 ⇒ 재할당
    • 원시 값을 직접 변경할 수 없음
      새로운 메모리 공간에 재할당한 원시값을 저장하면,
      변수는 재할당한 원시값을 가리킴
    • 변수가 참조하던 메모리공간의 주소가 변경됨
    • 원시값을 가진 변수는 재할당 이외 변경방법 없음

2.1 문자열과 불변성

  • 문자열의 특징 : 유사배열객체
    • 배열처럼 인덱스로 프로퍼티 값에 접근 가능
    • length 프로퍼티를 갖는 객체 (배열과 문자열만 있고, object는 없음)
    • length 프로퍼티를 가지면 for문으로 순회 가능
    • 원시값이라 변경 불가능
var str = 'string';

// 문자열은 유사 배열이므로 배열과 유사하게 인덱스를 사용해 각 문자에 접근할 수 있다.
console.log(str[0]); // s

// 원시 값인 문자열이 객체처럼 동작한다.
console.log(str.length); // 6
console.log(str.toUpperCase()); // STRING
var str = 'string';

// 문자열은 유사 배열이므로 배열과 유사하게 인덱스를 사용해 각 문자에 접근할 수 있다.
// 하지만 문자열은 원시 값이므로 변경할 수 없다. 이때 에러가 발생하지 않는다.
str[0] = 'S';

console.log(str); // string

2.2 값에 의한 전달

var score = 80;
var copy = score;

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

score = 100;

console.log(score); // 100
console.log(copy); // 80
  • 할당받는 변수에 할당되는 변수의 원시값이 복사되어 전달(값에 의한 전달)

  • 그러나 서로 다른 메모리 공간에 저장된 별개의 값이며,
    어느 한쪽에서 재할당이 일어나 값이 변경되더라도 서로 간섭할 수 없음.

  • (엄밀히 말하면 메모리 주소를 전달한다. 복사과정까지 같은 원시값을 참조하다가 재할당이 일어나면 새로운 메모리 공간에 재할당 값을 저장할 수도 있음)

3. 객체

3.1 변경 가능한 값

객체(참조) 타입의 값, 즉 객체는 변경 가능한 값(mutable value) 이다.

  • 원시 값을 할당한 변수는 메모리 주소를 통해 원시 값에 접근.
    즉, 원시 값을 할당한 변수는 원시 값 자체
  • 하지만 객체를 할당한 변수는 메모리 주소를 통해 참조 값(reference value) 에 접근. 참조 값은 생성된 객체가 저장된 메모리 공간의 주소
  • 원시값을 갖는 변수값을 변경하려면 only 재할당
  • 객체는 재할당없이 동적생성, 프로퍼티 값 갱신, 자체 삭제 가능
// 프로퍼티 값 갱신
person.name = 'Kim';

// 프로퍼티 동적 생성
person.address = 'Seoul'

console.log(person); // {name: "Kim", address: "Seoul"}
  • 객체는 메모리에 저장된 객체를 직접 수정가능하고,
    이 때 참조값은 바뀌지 않음

객체는 구조적 단점에 따른 부작용이 있다. 그것은 원시 값과는 다르게 여러 개의 식별자가 하나의 객체를 공유할 수 있다는 것이다.

3.2 참조에 의한 전달

var person = {
  name: 'Lee'
};

// 원본의 참조 값을 복사
// 원본과 사본 모두 동일한 객체를 가리킴 = 두개의 식별자가 하나의 객체를 공유
// 한 쪽에서 객체를 변경(새로운 객체 재할당이 아니라 프로퍼티 값을 변경하거나 추가삭제)하면 영향을 받음
var copy = person;
var person = {
  name: 'Lee'
};

// 참조 값을 복사(얕은 복사). copy와 person은 동일한 참조 값을 갖는다.
var copy = person;

// copy와 person은 동일한 객체를 참조한다.
console.log(copy === person); // true

// copy를 통해 객체를 변경한다.
copy.name = 'Kim';

// person을 통해 객체를 변경한다.
person.address = 'Seoul';

// copy와 person은 동일한 객체를 가리킨다.
// 따라서 어느 한쪽에서 객체를 변경하면 서로 영향을 주고받는다.
console.log(person); // {name: "Kim", address: "Seoul"}
console.log(copy); // {name: "Kim", address: "Seoul"}
  • "값에 의한 전달"과 "참조에 의한 전달"은 식별자가 기억하는 메모리 공간에 저장되어 있는 값을 복사해서 전달한다는 면에서는 동일
  • 다만 변수(메모리공간)에 저장되어 있는 값이 원시 값이냐 참조 값이냐의 차이
var person1 = {
	name : "Lee"
};

var person2 = {
	name: "Lee"
};

console.log(person1 === person2); // false 참조값이 다름
console.log(person1.name === pereon2.name); // true 원시값이 같음

좋은 웹페이지 즐겨찾기