객체


한 명의 사용자를 표현한다고 해봅시다. 이름, 이메일, 나이, 로그인 여부 같은 정보가 필요합니다. 이 정보들을 네 개의 개별 변수로 흩어놓을 수도 있지만, 이 값들은 원래 한 묶음이고, 따로 떼어놓으면 "그 사용자"를 가리킬 때마다 매번 네 가지를 함께 넘겨야 합니다. 객체를 쓰면 이 모든 정보를 하나의 값으로 모을 수 있고, 각 조각에는 찾아볼 수 있는 이름이 붙습니다. 여러분이 다룰 데이터 대부분, 사용자든 상품이든 장바구니든, 바로 이런 모양으로 도착합니다.
객체 만들기
**객체**는 이름이 붙은 값들의 모음으로, 중괄호로 작성합니다. 중괄호 안에는 key: value 쌍을 쉼표로 구분해서 나열합니다. 키는 이름이고, 값은 그 이름이 담고 있는 내용입니다:
const user = {
name: "지민",
age: 27,
};
console.log(user.name); // 지민값을 다시 읽어올 때는 점과 키를 사용합니다: user.name. 이것을 점 표기법이라고 부르며, 앞으로 가장 자주 쓰게 될 방식입니다. 왼쪽에 키, 오른쪽에 그 키가 담고 있는 값이라고 생각하면 됩니다.
값을 읽는 두 번째 방법도 있는데, 키를 문자열로 넣는 대괄호 표기법입니다:
console.log(user["name"]); // 지민대부분의 경우 점 표기법이 더 깔끔하게 읽히므로 그쪽을 사용하세요. 대괄호 표기법은 키가 일반적인 단어 형태가 아닐 때(예: 공백이 들어 있을 때)나, 키를 미리 알 수 없어서 다른 변수에 담겨 있을 때 제 역할을 합니다.
const product = {
title: "책상 램프",
price: 40,
inStock: true,
};
console.log(`${product.title} costs ${product.price}`); // 책상 램프 costs 40객체도 다른 것과 마찬가지로 하나의 값입니다. const에 저장할 수도 있고, 배열에 넣을 수도 있고, 함수에 넘기거나 반환할 수도 있습니다. 각 부분에 이름을 붙여주는 것이 바로 객체의 핵심입니다: product.price는 그 값이 무엇인지 말해주지만, 변수에 그냥 담긴 40은 그렇지 않습니다.
key: value 쌍으로 작성합니다. 값은 점과 키로 읽습니다, 예를 들면 user.name처럼요. 키에 특이한 문자가 들어 있거나 변수에 담겨 있을 때만 대괄호 표기법을 쓰세요. 객체 바꾸기
객체는 한번 만들었다고 고정되는 것이 아닙니다. 새로운 키를 추가하거나, 기존 키를 바꾸거나, 완전히 지울 수도 있습니다. 추가하거나 수정하려면 키에 값을 대입하세요:
const user = {
name: "지민",
};
user.age = 30; // 새로운 키 추가
user.name = "김지민"; // 기존 키 수정
console.log(user); // { name: "김지민", age: 30 }키가 이미 있으면 대입할 때 값이 교체됩니다. 없으면 새로 생깁니다. 키를 지우려면 delete를 사용하세요:
delete user.age;
console.log(user); // { name: "김지민" }여기서 사람들이 놀라는 부분이 있습니다. const로 만든 객체라도 속성은 여전히 바꿀 수 있습니다. const는 user라는 이름이 다른 객체를 가리키도록 재할당할 수 없다는 뜻이지만, 그 이름이 가리키는 객체 안의 내용은 자유롭게 바꿀 수 있습니다:
const cart = { total: 0 };
cart.total = 25; // 괜찮습니다, 내부 값을 바꾸는 것뿐이니까요
// cart = { total: 25 }; // 이건 오류입니다, 이름 자체를 재할당하는 것이니까요delete로 지울 수 있습니다. 놀라운 부분은 const입니다: user가 다른 객체를 가리키게 하는 것은 막아주지만, 그 객체 안의 내용을 바꾸는 것은 여전히 가능합니다. 저도 const가 모든 것을 잠가준다고 생각하는 버릇을 버리는 데 한참 걸렸습니다. 메서드와 this
객체 안의 값은 함수일 수도 있습니다. 그럴 때는 이를 **메서드**라고 부르는데, 객체가 저장하는 사실이 아니라 객체가 할 수 있는 동작을 뜻합니다. 점을 찍고 괄호를 붙여서 호출합니다:
const user = {
name: "지민",
greet() {
return `안녕하세요, 저는 ${this.name}입니다`;
},
};
console.log(user.greet()); // 안녕하세요, 저는 지민입니다여기서 새로 나오는 단어가 this입니다. user.greet()를 호출하면, this는 "이 메서드가 호출된 대상 객체"를 뜻하고, 여기서는 user입니다. 그래서 this.name은 같은 객체에서 name 키를 읽어옵니다. 이렇게 메서드는 값을 따로 넘겨받지 않고도 자기 객체의 값에 접근할 수 있습니다.
user.greet()처럼 점과 괄호로 호출합니다. 메서드 안에서 this는 그 메서드가 호출된 객체를 뜻하므로, this.name은 그 객체 자신의 name을 읽습니다. 이렇게 메서드는 자기 객체의 값에 접근합니다. 객체와 배열을 함께 쓰기
실제 데이터 대부분은 객체의 목록입니다: 여러 사용자, 여러 상품처럼, 각 객체가 같은 키를 가진 하나의 레코드입니다. 이런 객체들을 배열 안에 넣습니다:
const products = [
{ title: "책상 램프", price: 40 },
{ title: "노트", price: 6 },
{ title: "펜", price: 3 },
];
console.log(products[0].title); // 책상 램프먼저 위치로 하나의 객체에 접근하고(products[0]), 그다음 점으로 그 객체의 필드 중 하나에 접근합니다(.title). 이어 붙이면, products[0].title은 첫 번째 상품의 제목을 읽습니다.
모든 객체에서 어떤 필드를 읽으려면 배열을 순회하세요:
for (const product of products) {
console.log(product.title);
}
// 책상 램프
// 노트
// 펜반복문이 돌 때마다 product는 목록에서 하나의 객체가 되고, product.title은 그 객체의 제목을 읽습니다. 이 모양, 즉 순회하는 객체 배열이, 여러분이 하게 될 데이터 작업의 대부분입니다.
products[0]으로 하나에 접근하고, products[0].title로 필드에 접근합니다. 배열을 순회하면 모든 레코드를 처리할 수 있고, 이것이 여러분이 하게 될 데이터 작업 대부분의 패턴입니다. 다음으로 이어지는 객체
객체와 배열은 앞으로 계속 손이 가게 될 두 가지 구조이며, 여러분이 다루는 데이터 대부분은 이 둘이 어떤 형태로든 중첩된 모습입니다: 배열 필드를 가진 객체, 객체로 이루어진 배열, 그리고 이 둘의 조합입니다. 배열 메서드와 함께 쓰면 거의 어떤 데이터든 필요한 형태로 다듬을 수 있습니다.
다음 단계는 객체를 실제 페이지에서 활용하는 것입니다. DOM을 다루게 되면, 여러분이 읽고 바꾸는 요소들도 결국 객체이며, 키를 설정하고 메서드를 호출할 수 있으므로 여기서 배운 내용이 그대로 이어집니다.

