[Javascript] 원시 값과 객체의 비교

개발새발🦶·2022년 10월 13일
0
post-thumbnail

원시 타입

원시 타입 값은 변경 불가능한 값

  • 원시값을 변수에 할당하면 변수에는 실제 값이 저장 됨.
  • 원시 값 할당한 변수를 다른 변수에 할당하면 원본의 원시 값이 복사되어 전달 됨(값에 의한 전달).
  • 읽기 전용 값
  • 불변성을 갖는 원시 값을 할당한 변수는 재할당 말고 값을 변경할 방법이 없다.

객체타입

객체(참조) 타입의 값은 변경 가능한 값

  • 객체를 변수에 할당하면 참조 값이 저장된다.
  • 객체가 할당된 변수를 다른 변수에 할당하면 원본의 참조 값이 복사되어 전달 됨(참조에 의한 전달)

📌 원시 값

변경 불가능한 값

한번 생성된 원시 값은 읽기 전용 값으로서 변경할 수 없다. 변경 불가능하다는 것은 변수가 아니고 값에 대한 진술이다. 즉, 원시 값 자체를 변경할 수 없다는 뜻이지 변수 값을 변경할 수 없는 것은 아니다.

✅ 변수의 상대 개념인 상수는 재할당이 금지된 변수지만, 변경 불가능한 값은 아니다.

문자열과 불변성

문자열은 다른 원시 값과 비교할 때 한가지 특성이 있는데, 몇개의 문자로 이뤄지냐에 따라서 필요한 메모리 공간이 다르다.

  • 문자열은 원시 타입, 변경 불가
  • 변수에 재할당을 했을 때, 할당됐던 모든 문자열은 메모리에 존재
  • 유사 배열 객체미연서 이터러블이므로 배열과 유사하게 문자에 접근한다

유사 배열 객체
마치 배열처럼 인덱스로 프로퍼티에 접근가능하며, length 프로퍼티를 갖는 객체를 뜻한다.

let str = 'string';

// 유사 배열이므로 배열과 유사하세 인덱스를 사용해 각 문자 접근 가능
console.log(str[0]);  // s

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

// 문자열은 원시 값이므로 변경할 수 없다. 에러는 미발생
str[0] = 'S';
console.log(str); // string

값에 의한 전달

변수에 원시 값을 갖는 변수를 할당하면 할당받는 변수에는 할당되는 변수의 원시 값이 복사되어 전달된다. 이를 값에 의한 전달이라 한다.

  • 값에 의한 전달도 사실 값을 전달하는 것이 아닌, 메모리 주소를 전달한다.
  • 전달된 메모리 주소를 통해 메모리 공간에 접근하면 값을 참조할 수 있다.
// 원시 값 80이 복사되어 전달
// 따라서 score의 값을 변경해도 복사된 값이기 때문에 영향이 없다
let score = 80;
let copy = score;

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

// 값 80을 갖는 점에서는 동일하지만, 다른 메모리에 저장된 별개의 값
let tt = 80;
let dd = tt;

console.log(tt, dd);     // 80 80
console.log(tt === dd);  // true

✅ 엄밀히 따지면, 변수에는 값이 전달되는 것이 아니라 메모리 주소가 전달되기 때문에 변수와 같은 식별자는 값이 아니라 메모리 주소로 기억하고 있다.

✅ 결론은 두 변수의 원시 값은 서로 다른 메모리 공간에 저장되므로 재할당을 통해 값이 변경되어도 서로 간섭할 수 없다.

📌 객체

객체는 프로퍼티 개수가 정해져 있지 않으며, 동적으로 추가되고 삭제할 수 있다.
때문에 프로퍼티의 값에 제약이 없고, 원시 값과 같이 확보 할 메모리 공간의 크기를 사전에 정해 둘 수 없다.

  • 경우에 따라 크기가 천차만별이라 메모리를 많이 소비하기도 한다.
  • 클래스 없이 객체를 생성할 수 있음. 생성된 후에도 동적으로 프로퍼티, 메서드 추가 가능
  • 사용하기 편리하지만 비효율적

변경 가능한 값

객체(참조)는 변경 가능한 값이다. 객체를 할당한 변수가 기억한 메모리 공간에 접근하면 참조 값에 접근 가능하다. 참조 값은 생성된 객체가 저장된 메모리 공간의 주소 그 자체다

✅ 객체를 할당한 변수는 재할당 없이 객체를 직접 변경할 수 있다.

  • 프로퍼티 동적 추가
  • 프로퍼피 값 갱신
  • 프로퍼피 자체 삭제할 수 있다
  • 여러개의 식별자가 하나의 객체를 공유할 수 있다
let person = {
  name: 'lee';
}

// 값 갱신
person.name = 'kim';

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

const 0 = { x: { y: 1 } };

// 얕은 복사
const c1 = { ...o };
console.log(c1 === 0)      // false
console.log(c1.x === 0.x)  // true

// lodash의 cloneDeep을 사용한 깊은 복사
// npm으로 lodash 설치 후 node.js환경에서 실행
const _ = require('lodash');

// 깊은 복사
const c2 = _.cloneDeep(o);
console.log(c2 === 0)      // false
console.log(c1.x === 0.x)  // false

참조에 의한 전달

객체를 가르키는 변수를 다른 변수에 할당하면 원본의 참조 값이 복사되어 전달된다. 이를 참조에 의한 전달이라 함.

  • 원본 객체를 사본 객체에 할당하면 두개의 식별자가 하나의 객체를 공유한다
  • 때문에 어느 한 쪽의 객체를 변경시, 서로 영향을 주고 받는다.
profile
발로하는 코딩 정리기

0개의 댓글