1. 객체 (Object)
객체는 키(key)와 값(value)의 쌍으로 데이터를 묶는 자료형이다. 현실의 사물을 표현하기 좋으며, 값을 나타내는 속성(property)과 동작을 나타내는 메서드(method)로 구성된다.
객체 리터럴
중괄호 { } 안에 키: 값을 나열해 객체를 만든다.
let person = {
name: "John",
age: 25,
greet: function () {
console.log("Hello!");
}
};
// 속성 접근: 점 표기법
console.log(person.name); // John
// 속성 접근: 대괄호 표기법
console.log(person["age"]); // 25
// 메서드 호출
person.greet(); // Hello!John 25 Hello!
속성 추가·변경
let book = {};
book.title = "JS책"; // 점 표기법으로 추가
book["price"] = 20000; // 대괄호 표기법으로 추가
let key = "author";
book[key] = "최승호"; // 변수를 키로 사용 (대괄호만 가능)
console.log(book);{ title: 'JS책', price: 20000, author: '최승호' }
for...in — 객체 순회
객체의 모든 키를 하나씩 꺼내 반복한다.
let sports = { soccer: "축구", baseball: "야구" };
for (let key in sports) {
console.log(key, ":", sports[key]);
}soccer : 축구 baseball : 야구
2. 클래스와 this
클래스 (Class)
클래스는 객체를 찍어내는 설계도다. new 키워드로 클래스로부터 객체(인스턴스)를 생성한다.
class Person {
constructor(name, age) { // 객체 생성 시 자동 호출
this.name = name;
this.age = age;
}
greet() {
console.log(`안녕하세요, 저는 ${this.name}, ${this.age}살입니다.`);
}
}
let p1 = new Person("John", 25);
let p2 = new Person("Jane", 30);
p1.greet(); // 안녕하세요, 저는 John, 25살입니다.
p2.greet(); // 안녕하세요, 저는 Jane, 30살입니다.안녕하세요, 저는 John, 25살입니다. 안녕하세요, 저는 Jane, 30살입니다.
this 키워드
this는 메서드를 호출한 객체 자신을 가리킨다. 위 예시에서 p1.greet()를 호출하면 this는 p1을 가리키므로 this.name이 "John"이 된다.
let person = {
name: "John",
greet: function () {
console.log(`제 이름은 ${this.name}입니다.`);
}
};
person.greet(); // this → person → "John"제 이름은 John입니다.
생성자 함수와 프로토타입 (참고)
클래스 문법이 등장하기 전에는 생성자 함수로 객체를 찍어냈다. prototype에 메서드를 정의하면 모든 인스턴스가 공유한다.
function Person(name, age) {
this.name = name;
this.age = age;
}
Person.prototype.greet = function () {
console.log(`Hello, ${this.name}!`);
};
let john = new Person("John", 30);
john.greet(); // Hello, John!Hello, John!
3. 배열 (Array)
배열은 순서가 있는 값의 목록이다. 인덱스(번호)는 0부터 시작한다.
let fruits = ["apple", "banana", "orange"];
console.log(fruits[0]); // "apple"
console.log(fruits[2]); // "orange"
console.log(fruits.length); // 3apple orange 3
배열 반복하기
let fruits = ["apple", "banana", "orange"];
// for문
for (let i = 0; i < fruits.length; i++) {
console.log(fruits[i]);
}
// forEach 메서드 (요소와 인덱스를 콜백으로 받음)
fruits.forEach(function (fruit, index) {
console.log(index, fruit);
});apple banana orange 0 apple 1 banana 2 orange
forEach는 배열의 각 요소를 처음부터 끝까지 한 번씩 순회하며 콜백 함수를 실행한다. 콜백은 (요소, 인덱스)를 차례로 받는다. for문보다 간결해 단순 반복에 자주 쓴다.
forEach vs map
둘 다 모든 요소를 순회하지만 반환값이 다르다.
forEach: 각 요소로 무언가를 "실행"만 하고 반환값이 없다(undefined). 화면 출력·로그처럼 결과를 따로 모을 필요가 없을 때 쓴다.map: 각 요소를 변형해 새 배열을 반환한다. 가공한 결과를 다시 사용할 때 쓴다.
[1, 2, 3].forEach(n => n * 2); // undefined (결과를 받을 수 없음)
[1, 2, 3].map(n => n * 2); // [2, 4, 6] (새 배열 반환)4. 배열 메서드
추가·제거 메서드
메서드 | 동작 |
|---|---|
| 끝에 요소 추가 |
| 마지막 요소 제거 후 반환 |
| 앞에 요소 추가 |
| 첫 요소 제거 후 반환 |
| 일부를 잘라 새 배열 반환 (원본 유지) |
| 요소를 제거/추가 (원본 변경) |
let fruits = ["apple", "banana"];
fruits.push("cherry");
console.log(fruits); // ['apple', 'banana', 'cherry']
let last = fruits.pop();
console.log(last); // 'cherry'
console.log(fruits); // ['apple', 'banana'][ 'apple', 'banana', 'cherry' ] cherry [ 'apple', 'banana' ]
고차 함수 메서드 ⭐
실무에서 가장 많이 쓰는 메서드들로, 콜백 함수를 인수로 받는다. 화살표 함수와 함께 쓰면 매우 간결하다.
메서드 | 동작 | 반환 |
|---|---|---|
| 각 요소를 변형 | 새 배열 |
| 조건을 만족하는 요소만 추림 | 새 배열 |
| 모든 요소를 하나의 값으로 누적 | 단일 값 |
| 조건을 만족하는 첫 요소 | 요소 |
| 하나라도 조건을 만족하면 | Boolean |
| 모두 조건을 만족하면 | Boolean |
const numbers = [1, 2, 3, 4, 5];
// map: 각 요소를 2배로 변형
console.log(numbers.map(n => n * 2)); // [2, 4, 6, 8, 10]
// filter: 짝수만 추림
console.log(numbers.filter(n => n % 2 === 0)); // [2, 4]
// reduce: 모든 요소의 합 (acc=누적값, cur=현재값, 0=초기값)
console.log(numbers.reduce((acc, cur) => acc + cur, 0)); // 15
// find: 3보다 큰 첫 요소
console.log(numbers.find(n => n > 3)); // 4
// some / every
console.log(numbers.some(n => n >= 5)); // true
console.log(numbers.every(n => n <= 8)); // true[ 2, 4, 6, 8, 10 ] [ 2, 4 ] 15 4 true true
for문 대신 고차 함수
map·filter·reduce는 "무엇을 할지"가 코드에 그대로 드러나 읽기 쉽고 버그가 적다. 객체 배열을 다룰 때 특히 강력하다.
const students = [
{ name: "철수", math: 90 },
{ name: "영희", math: 60 }
];
// 수학 80점 이상인 학생 이름만 뽑기
const pass = students.filter(s => s.math >= 80).map(s => s.name);
console.log(pass); // ['철수']5. 구조 분해 할당 (Destructuring)
ES6 기능으로, 배열이나 객체의 값을 변수로 한 번에 추출한다.
배열 구조 분해
const numbers = [1, 2, 3];
const [first, second, third] = numbers;
console.log(first, second, third); // 1 2 3
// 일부 건너뛰기 / 기본값
const [a, , c] = [10, 20, 30];
console.log(a, c); // 10 30
const [x, y = 99] = [5];
console.log(x, y); // 5 991 2 3 10 30 5 99
객체 구조 분해
const person = { name: "John", age: 30 };
const { name, age } = person;
console.log(name, age); // John 30
// 새로운 변수 이름으로 받기
const { name: userName } = person;
console.log(userName); // John
// 함수 매개변수에서 바로 구조 분해
function greet({ name, age }) {
console.log(`${name} (${age})`);
}
greet(person); // John (30)John 30 John John (30)
6. 스프레드 연산자와 Rest 매개변수
둘 다 ... 기호를 쓰지만 역할이 반대다.
스프레드 연산자 — 펼치기
배열·객체의 요소를 펼쳐서 복사하거나 합칠 때 쓴다.
// 배열 합치기 / 복사
const arr1 = [1, 2, 3];
const arr2 = [...arr1, 4, 5];
console.log(arr2); // [1, 2, 3, 4, 5]
// 객체 합치기 / 수정
const person = { name: "철수", age: 25 };
const updated = { ...person, age: 26 };
console.log(updated); // { name: '철수', age: 26 }
// 함수 인자로 펼치기
console.log(Math.max(...[1, 5, 3, 9, 2])); // 9[ 1, 2, 3, 4, 5 ] { name: '철수', age: 26 } 9
Rest 매개변수 — 모으기
여러 개의 인수를 하나의 배열로 모아서 받는다.
function sum(...numbers) {
return numbers.reduce((acc, n) => acc + n, 0);
}
console.log(sum(1, 2, 3)); // 6
console.log(sum(1, 2, 3, 4, 5)); // 15
// 고정 매개변수 + 나머지
function introduce(name, ...hobbies) {
console.log(`${name}의 취미: ${hobbies.join(", ")}`);
}
introduce("영희", "독서", "운동", "요리");6 15 영희의 취미: 독서, 운동, 요리
스프레드 vs Rest 한 줄 요약
스프레드: 모여 있는 것을 펼친다 (
[...arr],{...obj},fn(...args))Rest: 흩어진 것을 모은다 (
function fn(...args),const [a, ...rest] = arr)