객체 리터럴
1. 객체란?
- 자바스크립트에서 원시 값을 제외한 모든 값.
- 원시값은 불변(immutable), 객체는 변경이 가능한 값(mutable)
const obj = {
num : 0,
increase: fuction(){
this.num++;
}
}
2. 프로퍼티
- 식별자 네이밍을 따르지 않는 key는 ''로 감싸주어야 한다.
const obj = { 'a b' : 1 }
obj['a b'];
const key = 'car';
const obj = { [key] : 1 }
obj;
- 키에 숫자타입을 사용하면 문자열로 변환된다.
- 키를 중복 선언하면 나중에 선언한 프로퍼티로 덮어쓴다.
3. 메서드
4. 객체 리터럴의 확장 기능
- 프로퍼티 축약 : 프로퍼티 value로 사용할 변수와 프로퍼티 key가 동일한 이름일 때 축약 가능
const x = 1, y = 2;
const obj = { x, y }
const obj = {
name: "Lee",
sayHi() {
console.log("Hi!" + this.name);
},
};
원시 값과 객체의 비교
1. 차이점
- 원시타입은 변경 불가능한 값, 객체(참조)타입은 변경 가능한 값
- 원시 값을 변수에 할당하면 변수에는 실제 값이 저장, 객체를 변수에 할당하면 변수에는 참조 값이 저장.
- 원시 값을 갖는 변수를 다른 변수에 할당하면 원본의 원시 값이 복사되어 전달 -> pass by value
- 객체를 가리키는 변수를 다른 변수에 할당하면 원본의 참조 값이 복사되어 전달 -> pass by reference
- 하지만 엄격하게 표현하면 변수에는 값이 전달되는 것이 아니라 메모리 주소가 전달된다. 식별자는 값이 아니라 메모리 주소를 기억하고 있기 때문
2. 원시 값
- 변수에 원시 값을 할당하면 새로운 메모리 공간을 확보하고 원시 값을 저장한 후, 식별자는 새로운 메모리 공간을 기억한다.
- 다른 원시 값을 재할당해도 위와 같은 과정이 계속 일어날 뿐, 원시 값 자체는 절대 변하지 않는다. 더 이상 참조되지 않는(식별자가 기억하지 않는) 메모리 공간의 값은 가비지 컬렉션에 의해 제거된다.
- 문자열은 유사 배열 객체지만 결국 값을 변경할 수 없다.
- 변수에 원시 값을 갖는 변수를 할당하면 서로 다른 메모리 공간에 저장된 별개의 값이 되어 서로 간섭할 수 없다.
👀 유사배열 객체
- 배열처럼 인덱스로 프로퍼티값에 접근할 수 있고 length 프로퍼티를 갖는 객체.
- name[0] = "k"은 에러가 나지 않지만 값은 변경되지 않는다.
- 배열 메서드를 사용하면 에러가 난다.
- DOM 조작시 querySelectorAll로 가져온 NodeList도 유사배열 객체다.
3. 객체
변수에 객체를 할당했을 때
- 변수에 객체를 할당하면 메모리의 두 공간을 확보한다.
- a공간에 실제 객체를 저장하고 b공간에는 객체가 저장된 공간을 가리키는 참조 값을 저장한다.
- 식별자는 참조 값을 기억한다.
- 식별자 -> 메모리에 저장된 참조 값(객체의 위치 정보) -> 해당 위치에 저장된 객체
- 객체를 가리키는 변수를 다른 변수에 할당하면 객체가 저장된 공간이 복사되는 것이 아니라 참조 값이 복사되어 전달된다. 결과적으로 각각의 변수는 같은 객체를 가리키게 된다.
구조적 이유와 문제점
- 객체는 크기가 매우 클수도 있고 일정하지 않기 때문에 객체를 변경할 때마다 원시 값처럼 이전 값을 복사해서 새롭게 생성한다면 성능에 문제가 생길 수 있다.
- 생성 비용을 절약하여 성능을 향상 시키기 위해 객체는 변경 가능한 값으로 설계
- 그러나 위와 같은 이유로 객체는 여러개의 식별자가 하나의 객체를 공유할 수 있다는 단점이 있다.
해결 방법, 얕은 복사와 깊은 복사
- 얕은 복사 : 객체의 첫 번째 레벨(1단계)의 속성만 복사
- 스프레드 문법
- Array.slice()
- Array.concat()
- 깊은 복사 : 얕은 복사의 경우 프로퍼티의 value가 객체일 경우 그 객체를 공유하게 되는 문제가 생긴다. 반면 깊은 복사는 객체의 모든 레벨(여러 단계)의 속성을 완전히 복사한다.(하위 객체가 없다면 얕은 복사로도 충분하다는 뜻이기도 하다)
- JSON.parse()와 JSON.stringify()
📖 모던자바스크립트 딥다이브 10장 객체 리터럴(124p), 11장 원시 값과 객체의 비교(137p)