모던 자바스크립트 Deep Dive 10장
개요
자바스크립트의 모든것은 원시값을 제외하고 객체로 이뤄져있다
객체는 변경 가능한 값이다
핵심 개념
- 객체는 프로퍼티(상태)와 메서드(동작)의 집합
- 객체 리터럴 {}로 가장 간단하게 생성 가능
- 프로퍼티 키는 문자열 또는 심벌, 값은 아무거나 OK
객체란?
원시값 또는 다른 객체를 하나로 구성한 복합적인 자료구조임
프로퍼티는 객체의 상태를 나타내는 값, 메서드는 프로퍼티를 참조하고 조작할 수 있는 동작
참고로 객체 == 함수 수준으로 연관성이 짙다고 함
객체 리터럴에 의한 객체 생성
{자바스크립트의 객체 생성 방식들 중 가장 일반적인 방법}
보통의 언어들은 new 연산자와 함께 생성자를 호출하여 인스턴스를 생성한다
// 이궈궈던 ㅋㅋ
ResponseDTO dto = new ResponseDTO(name, age);
근데 자바 스크립트 이놈은 ㅋㅋ 타입도 필요없고 객체 리터럴 이라는 숭한 방식을 사용할 수 있다고 한다
var person = {
name: 'Lee',
sayHello: function() {
console.log(`Hello! My name is ${this.name}`)
}
};
console.log(typeof person); // object
console.log(person); // {name: 'Lee', sayHello: ƒ}
이것 말고도
- Object 생성자 함수
- 생성자 함수
- Object.create 메서드
- 클래스(ES6)
을 사용해서 만들 수 있다 함
위에서 확인할 수 있다 싶히 중괄호 내에 0개 이상의 프로퍼티를 정의하기만 하면 끝
프로퍼티를 정의하지 않으면 빈 오브젝트가 된다고 함
// 크 아 악
var test = {}
console.log(typeof test) // object
객체 리터럴과 코드블록을 헷갈리지 않게 주의
객체 리터럴은 값으로 평가되어 뒤에 세미클론을 붙인다
순서는 다음과 같음
- 컴파일 초기화 단계에서 변수를 초기화한다 (호이스팅)
- 리터럴 문법 만나는 순간 힙에 빈 객체 생성
- 만약 값이 이미 있다면 재사용, 없다면 새롭게 할당
- name 프로퍼티에 값 추가
- 해당 참조값을 변수에 할당
프로퍼티
객체는 프로퍼티의 집합임
프로퍼티를 나열할때는 쉼표로 구분하고 마지막에는 안찍어도 된단다
프로퍼티 키는 빈 문자열을 포함해 문자열로 평가되는 모든 값과 심벌값을 사용할 수 있다
프로퍼티 값은 그냥 모든값을 할당해줄 수 있음
여기서 좀 웃긴게 네이밍 규칙을 준수하는 문자열은 '', "" 을 안붙여도 key로 사용된다고 함
var person = {
firstName: 'Byeongjun jeon' // 갸아악
}
얘는 다음과 같이 동작함
1. value가 Symbol이면 → 그대로 사용
2. 아니면 → ToPrimitive(value, "string")
3. 그 다음 → String으로 변환
ToPrimitive가 좀 골때리는데 object가 들어가면 key값이 [Object object] 가 되어부린다는것 ㅋㅋ
const obj = {
[!""]: "value"
};
console.log(obj); // { "true": "value" } 아오 ㅋㅋ
따라서 단순 수투링으로 평가되기 때문에 예약어도 사용 가능한것 ㅋㅋ
같은 프로퍼티가 있으면 더 아래 있는 값으로 덮여씌워지고 오류가 안뜬다 함
메서드
걍 프로퍼티 값이 함수일 경우 구별하기 위해 메서드라고 한다 함
프로퍼티 접근
마침표 표기법과 대괄호 표기법
const person = {
name: "Lee",
age: 20,
"full-name": "Lee JS"
};
console.log(person.name); // "Lee"
console.log(person.age); // 20
console.log(person["name"]); // "Lee"
console.log(person["full-name"]); // "Lee JS"
마침표 표기법이 깔끔하다잉
대괄호 표기법은 꼭 따옴표로 감싸줘야함. 안그러면 식별자로 평가하기 때문에 레퍼런스 에러가 난다고 함
또 레전드 예제 발생 ㅋㅋㅋ 보면서도 어이가 없네
var person = {
'last-name': 'Jeon',
1: 10
}
// 아오 ㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋ
person.'last-name'; // SyntaxError
person.last-name; // Web에서는 NaN, Node.js에서는 ReferenceError
// 이건 예상함
person.1; // SyntaxError
person.'1'; // SyntaxError
person[1]; // 10
person['1']; // 10
왜 Web에서는 NaN, Node에서는 ReferenceError가 날까??
- 기본적으로 자바스크립트는 person.last를 먼저 평가함.
- person.last라는 프로퍼티가 없음으로 undefined로 평가된다
- 따라서 undefined - name 이 되부림 ㅋㅋㅋㅋㅋㅋㅋ
- 이때 name은 식별자로 평가되는데
- node는 name이라는 값을 찾을 수 없음으로 ReferenceError 즉 name 에서 에러가 터진다는것
- 근데 웹에서는 이미 name이라는 값이 윈도우 브라우저에 전역변수로 존재한단다
- 그게 빈 문자열 "" 임 (window.name은 string 타입)
- - 연산자가 양쪽을 숫자로 강제 변환 → Number(undefined) = NaN, Number("") = 0
- NaN - 0 = NaN ㅋㅋ
나는 완전히 멘탈이 나가버리는 ㅋㅋ
프로퍼티 값 갱신, 생성, 삭제
var person = {
name: 'Lee'
}
// 갱신
person.name = "Kim";
// 생성
person.age = 20;
// 삭제
delete person.name;
ES6에서 추가된 객체 리터럴의 확장 기능
프로퍼티 축약 표현
let x = 1, y = 2;
const obj = { x, y };
console.log(obj); // { x: 1, y: 2 } 좀 편함
계산된 프로퍼티 이름
ES5에서는 객체 리터럴 외부에서만 대괄호 표기법으로 동적 키를 만들 수 있었는데, ES6부터는 객체 리터럴 내부에서도 가능해짐
// ES5
var prefix = 'prop';
var i = 0;
var obj = {};
obj[prefix + '-' + ++i] = i;
obj[prefix + '-' + ++i] = i;
// ES6 — 객체 리터럴 안에서 바로 가능
const obj2 = {
[`${prefix}-${++i}`]: i,
[`${prefix}-${++i}`]: i,
};
메서드 축약 표현
// ES5
var obj = {
name: 'Lee',
sayHi: function() {
console.log('Hi! ' + this.name);
}
};
// ES6 — function 키워드 생략
const obj2 = {
name: 'Lee',
sayHi() {
console.log('Hi! ' + this.name);
}
};
핵심 포인트
- 자바스크립트는 원시값 빼고 전부 객체, 객체는 변경 가능한(mutable) 값
- 프로퍼티 키는 내부적으로 문자열로 변환됨 (ToPrimitive → String), 그래서 예약어도 키로 쓸 수 있음
- 존재하지 않는 프로퍼티에 접근하면 에러가 아니라 undefined 반환 — person.last-name 같은 함정 주의
- ES6 확장: 프로퍼티 축약, 계산된 프로퍼티 이름, 메서드 축약으로 객체 리터럴이 훨씬 간결해짐
참고 자료
- 모던 자바스크립트 Deep Dive 10장
- 타입 변환과 단축 평가 — 9장에서 다룬 타입 변환이 객체 프로퍼티 접근 시에도 적용
'코딩딩 > Javascript' 카테고리의 다른 글
| 날것 - 함수 (0) | 2026.05.12 |
|---|---|
| 날것 - 원시 값과 객체의 비교 (1) | 2026.04.15 |
| 날것 - 타입 변환과 단축 평가 (0) | 2026.04.01 |
| 날것 - 제어문 (Control Flow Statements) (0) | 2026.03.25 |
| 날것 - 연산자 (0) | 2026.03.18 |