본문으로 건너뛰기

안동민 개발노트

본문 시작

객체와 배열 기초

객체의 속성·메서드와 배열의 순서 있는 요소를 생성·조회·수정·삭제하며 복합 데이터를 구조화합니다.

이전 장에서는 숫자, 문자열, 불리언 같은 기본 데이터 타입과 변수 저장 방식을 배웠습니다.

하지만 실제 웹 애플리케이션에서는 사용자 정보, 상품 목록, 게시글처럼 연관된 데이터를 묶어 관리해야 하는 경우가 훨씬 많습니다.

이런 복합 데이터를 효율적으로 관리하기 위해 자바스크립트는 객체(Object)배열(Array)을 제공합니다.

이번 장에서는 객체/배열의 생성, 데이터 추가, 접근, 조작의 기본 흐름을 정리합니다.

객체/배열 설계 기준

객체는 이름으로 값을 묶고 배열은 순서 있는 목록을 다루며, 참조와 복사 규칙을 이해해야 상태 버그를 줄일 수 있다.

자료 형태적합한 경우주요 조작주의점
Object한 대상의 속성을 이름으로 묶음property access, destructuring없는 속성 접근
Array순서 있는 여러 값을 묶음map, filter, reduceindex 의미가 흐려짐
Nested data객체 안 배열 또는 배열 안 객체path access깊은 값 변경 추적 어려움
Reference객체와 배열은 참조가 복사됨spread, structuredClone얕은 복사와 mutation 혼동
Transform새 배열이나 객체로 변환map/filter/reduce원본 변경 여부 불명확

객체: 연관된 데이터를 묶는 컨테이너

객체와 배열 기초에서는 값의 변화, 실행 순서, 화면 반응을 함께 봅니다.

객체는 관련 값을 이름 붙은 속성으로 묶어 의미를 만든다

배열이 순서 중심이라면 객체는 이름 중심이다. 같은 데이터라도 접근 방식과 표현 의도가 달라진다.

비교객체배열판단 기준
접근 방식key로 값 접근index로 값 접근이름이 중요한가 순서가 중요한가
의미한 대상의 속성 표현같은 종류의 목록 표현데이터가 하나의 대상인가
순회Object.keys/entriesmap, forEach반복 작업이 많은가
변경속성 추가·수정push, splice, filter원본 변경을 피할 수 있는가
표현{name, age}[item1, item2]읽는 사람이 구조를 즉시 알 수 있는가

객체는 여러 개의 속성(property)을 담는 컨테이너라고 할 수 있습니다.

각 속성은 이름(key)값(value)의 쌍으로 이루어져 있습니다.

마치 사전에서 단어(key)와 그 의미(value)가 짝을 이루는 것과 같습니다.

객체는 특정한 에 대한 정보를 구조화하여 표현할 때 매우 유용합니다.

객체 생성하기

가장 일반적인 객체 생성 방법은 중괄호 {}를 사용하는 객체 리터럴(Object Literal) 방식입니다.

// 사용자 정보를 담는 객체
let user = {
    name: "김민준",      // 'name'은 속성 이름(키), "김민준"은 속성 값
    age: 28,           // 'age'는 숫자 타입 값
    isStudent: false,  // 'isStudent'는 불리언 타입 값
    email: "minjun@example.com",
    "favorite-color": "blue" // 속성 이름에 하이픈이 포함되면 따옴표로 묶어야 합니다.
};

console.log(user);
/*
결과:
{
  name: '김민준',
  age: 28,
  isStudent: false,
  email: 'minjun@example.com',
  'favorite-color': 'blue'
}
*/

각 속성 이름(키)과 값은 콜론(:)으로 구분하며, 각 속성 쌍은 쉼표(,)로 구분합니다.

객체 속성 접근하기

객체에 저장된 속성 값에 접근하는 방법은 두 가지가 있습니다.

점 표기법 (Dot Notation): 가장 흔하게 사용되는 방법으로, 객체이름.속성_이름 형식으로 접근합니다.

속성 이름이 유효한 자바스크립트 식별자(변수 이름 규칙과 유사)일 때 사용합니다.

console.log(user.name);         // 결과: 김민준
console.log(user.age);          // 결과: 28
console.log(user.email);        // 결과: minjun@example.com

대괄호 표기법 (Bracket Notation): 객체이름['속성_이름'] 형식으로 접근합니다.

속성 이름이 변수에 저장되어 있거나, 하이픈(-)과 같이 유효하지 않은 식별자 문자를 포함할 때 사용합니다.

console.log(user['name']);       // 결과: 김민준 (점 표기법과 동일한 결과)
console.log(user['favorite-color']); // 결과: blue (하이픈 때문에 대괄호 필수)

let keyName = "age";
console.log(user[keyName]);      // 결과: 28 (변수를 통해 속성 이름에 접근)

객체 속성 추가 및 변경하기

객체에 새로운 속성을 추가하거나 기존 속성의 값을 변경할 수 있습니다.

let product = {
    name: "노트북",
    price: 1200000
};

// 속성 추가
product.manufacturer = "XYZ전자"; // 새로운 manufacturer 속성 추가
product['release-date'] = "2024-05-01"; // 대괄호 표기법으로 속성 추가

console.log(product);
/*
결과:
{
  name: '노트북',
  price: 1200000,
  manufacturer: 'XYZ전자',
  'release-date': '2024-05-01'
}
*/

// 속성 값 변경
product.price = 1150000; // 기존 price 속성 값 변경
console.log(product.price); // 결과: 1150000

객체 속성 삭제하기

delete 연산자를 사용하여 객체의 특정 속성을 제거할 수 있습니다.

let student = {
    id: 101,
    name: "박지성",
    grade: 3
};

console.log(student); // { id: 101, name: '박지성', grade: 3 }

delete student.grade; // grade 속성 삭제
console.log(student); // { id: 101, name: '박지성' }

// delete student['id']; // 대괄호 표기법으로도 삭제 가능

객체 내의 함수 (메서드)

객체의 속성 값으로는 일반적인 데이터뿐만 아니라 함수도 올 수 있습니다.

객체 내부에 정의된 함수를 메서드(Method)라고 부릅니다.

메서드는 해당 객체의 데이터를 조작하거나 객체와 관련된 동작을 수행할 때 사용됩니다.

let person = {
    name: "이수진",
    age: 22,
    // sayHello라는 메서드 정의
    sayHello: function() {
        console.log(`안녕하세요, 제 이름은 ${this.name}입니다.`);
        // this는 현재 객체(여기서는 person)를 가리킵니다.
    },
    // ES6에서 도입된 간결한 메서드 정의 문법
    introduce() {
        console.log(`저는 ${this.age}살 ${this.name}입니다.`);
    }
};

person.sayHello();   // 결과: 안녕하세요, 제 이름은 이수진입니다.
person.introduce(); // 결과: 저는 22살 이수진입니다.

메서드 내부에서 this 키워드를 사용하면, 해당 메서드를 호출한 객체 자신을 참조할 수 있습니다.

이는 객체 내부의 다른 속성 값에 접근할 때 매우 유용합니다.


배열: 순서가 있는 데이터 목록

배열(Array)은 여러 개의 값을 순서대로 나열하여 저장하는 특별한 형태의 객체입니다.

객체가 키-값 쌍으로 데이터를 저장하는 반면, 배열은 순서(index)를 기반으로 데이터를 관리합니다.

같은 종류의 데이터를 여러 개 모아둘 때 주로 사용됩니다.

배열 생성하기

배열은 대괄호 []를 사용하여 생성하며, 각 요소는 쉼표(,)로 구분합니다.

// 숫자 배열
let numbers = [10, 20, 30, 40, 50];

// 문자열 배열
let fruits = ["사과", "바나나", "오렌지", "포도"];

// 다양한 타입의 요소를 포함하는 배열 (권장하지는 않음)
let mixedArray = ["Hello", 123, true, { id: 1 }];

// 빈 배열
let emptyArray = [];

console.log(numbers); // 결과: [ 10, 20, 30, 40, 50 ]
console.log(fruits);  // 결과: [ '사과', '바나나', '오렌지', '포도' ]

배열 요소 접근하기

배열의 각 요소는 고유한 인덱스(index)를 가지고 있습니다.

인덱스는 0부터 시작하는 정수입니다.

배열이름[인덱스] 형식으로 요소에 접근합니다.

let colors = ["red", "green", "blue"];

console.log(colors[0]); // 결과: red (첫 번째 요소)
console.log(colors[1]); // 결과: green (두 번째 요소)
console.log(colors[2]); // 결과: blue (세 번째 요소)

console.log(colors[3]); // 결과: undefined (인덱스를 벗어나면 undefined)
배열의 길이 (length 속성)

배열의 총 요소 개수는 length 속성을 통해 알 수 있습니다.

console.log(fruits.length); // 결과: 4

length 속성은 배열의 마지막 인덱스를 알거나, 반복문을 사용할 때 유용합니다.

배열 요소 추가 및 변경하기

배열의 특정 인덱스에 접근하여 값을 변경하거나, 새로운 요소를 추가할 수 있습니다.

let tasks = ["운동하기", "공부하기", "요리하기"];
console.log(tasks); // 결과: [ '운동하기', '공부하기', '요리하기' ]

// 요소 변경 (인덱스를 통해)
tasks[0] = "산책하기";
console.log(tasks); // 결과: [ '산책하기', '공부하기', '요리하기' ]

// 요소 추가 (length 속성을 이용)
tasks[tasks.length] = "책 읽기"; // 배열의 마지막에 추가
console.log(tasks); // 결과: [ '산책하기', '공부하기', '요리하기', '책 읽기' ]

// `push()` 메서드를 이용한 추가 (더 권장되는 방법)
tasks.push("청소하기"); // 배열의 마지막에 요소 추가
console.log(tasks); // 결과: [ '산책하기', '공부하기', '요리하기', '책 읽기', '청소하기' ]

// `unshift()` 메서드를 이용한 추가 (배열의 맨 앞에 추가)
tasks.unshift("명상하기"); // 배열의 맨 앞에 요소 추가
console.log(tasks); // 결과: [ '명상하기', '산책하기', '공부하기', '요리하기', '책 읽기', '청소하기' ]

배열 요소 삭제하기

배열에서 요소를 삭제하는 여러 방법이 있습니다.

let items = ["A", "B", "C", "D"];
console.log(items); // 결과: [ 'A', 'B', 'C', 'D' ]

// `pop()` 메서드: 배열의 마지막 요소를 제거하고 반환합니다.
let lastItem = items.pop();
console.log(items);     // 결과: [ 'A', 'B', 'C' ]
console.log(lastItem);  // 결과: D

// `shift()` 메서드: 배열의 첫 번째 요소를 제거하고 반환합니다.
let firstItem = items.shift();
console.log(items);     // 결과: [ 'B', 'C' ]
console.log(firstItem); // 결과: A

// `splice()` 메서드: 특정 인덱스부터 원하는 개수만큼 요소를 제거할 수 있습니다.
// items.splice(시작_인덱스, 제거할_개수);
items.splice(0, 1); // 인덱스 0부터 1개 제거 (B 제거)
console.log(items); // 결과: [ 'C' ]

items.push("D", "E"); // 다시 추가
console.log(items); // 결과: [ 'C', 'D', 'E' ]

items.splice(1, 2); // 인덱스 1부터 2개 제거 (D, E 제거)
console.log(items); // 결과: [ 'C' ]

splice() 메서드는 요소를 추가하거나 교체하는 데도 사용될 수 있는 강력한 메서드입니다.

(추가적인 활용은 심화 학습에서 다루겠습니다.)

배열 순회하기 (반복문과 함께)

배열의 모든 요소를 하나씩 접근하여 어떤 작업을 수행해야 할 때 반복문을 사용합니다.

let students = ["민수", "지영", "태호"];

// 1. for 문을 이용한 순회 (가장 기본적인 방법)
for (let i = 0; i < students.length; i++) {
    console.log(`${i + 1}번째 학생: ${students[i]}`);
}
/*
결과:
1번째 학생: 민수
2번째 학생: 지영
3번째 학생: 태호
*/

// 2. for...of 문을 이용한 순회 (ES6, 배열 요소에 직접 접근)
for (let student of students) {
    console.log(`학생 이름: ${student}`);
}
/*
결과:
학생 이름: 민수
학생 이름: 지영
학생 이름: 태호
*/

// 3. forEach() 메서드를 이용한 순회 (배열 메서드, 함수 활용)
// forEach(콜백함수)
students.forEach(function(student, index) { // 각 요소와 인덱스를 인자로 받습니다.
    console.log(`${index + 1}. ${student}`);
});
/*
결과:
1. 민수
2. 지영
3. 태호
*/

// 화살표 함수로 더 간결하게 표현 가능
students.forEach((student, index) => {
    console.log(`${index + 1}. ${student}`);
});

for...of 문과 forEach() 메서드는 for 문보다 더 직관적이고 간결하게 배열을 순회할 수 있게 해줍니다.

객체와 배열 접근 방식 비교

이름 붙은 속성이 중요하면 객체, 순서대로 반복할 목록이면 배열을 먼저 떠올립니다.

  1. 하나의 대상을 설명

    name, age, email처럼 의미가 있는 이름

  2. value

    문자열, 숫자, 함수 등 연결된 값

  3. 여러 값을 순서대로 저장

    0부터 시작하는 위치 번호로 접근

  4. method

    push, pop, forEach로 목록을 조작

객체와 배열은 모두 데이터를 묶지만, 읽는 방식과 변경 패턴이 다릅니다.

아래 기준표처럼 이름으로 찾는 데이터인지, 순서대로 처리할 데이터인지 먼저 구분하면 구조 선택이 쉬워집니다.

객체와 배열 선택 기준표

데이터 구조는 저장 방식보다 읽는 방식에 맞춰 고르면 이후 수정과 반복 처리가 쉬워집니다.

  1. 객체를 고를 때

    름, 나이, 가격처럼 의미 있는 키로 값을 찾고, 하나의 대상 상태를 묶고 싶을 때 적합합니다.

  2. 배열을 고를 때

    목록 순서가 중요하거나 같은 형태의 값을 반복 처리해야 할 때 적합합니다.

  3. read
    찾는 기준

    키로 찾으면 객체, 인덱스와 순서로 찾으면 배열입니다.

  4. update
    변경 방식

    속성 변경은 점 표기법, 목록 변경은 `push`와 `splice`를 사용합니다.

  5. 루프
    반복 처리

    배열은 `for...of`, 객체는 필요한 키를 골라 읽습니다.

복합 데이터를 다룰 때는 구조 선택 이후에도 접근 방식, 변경 메서드, 반복 방법을 함께 맞춰야 코드가 흔들리지 않습니다.

객체 배열 조작 점검표

복합 데이터는 구조를 고른 뒤에도 읽기, 변경, 반복 방식이 서로 맞아야 안정적입니다.

  1. shape
    데이터 모양

    한 대상의 속성인지, 같은 형태의 여러 항목인지 먼저 나눕니다.

  2. access
    접근 방식

    객체는 키로 읽고, 배열은 인덱스나 반복으로 읽습니다.

  3. update
    변경 지점

    속성 변경과 요소 추가를 같은 줄에 섞지 않고 단계로 나눕니다.

  4. method
    메서드 선택

    끝에 추가하면 `push`, 앞에서 제거하면 `shift`처럼 목적에 맞춥니다.

  5. 루프
    순회 범위

    전체 목록인지, 특정 조건의 항목만 볼 것인지 정하고 반복합니다.


객체와 배열 기본 정리

이번 장에서는 자바스크립트에서 여러 데이터를 효과적으로 관리하기 위한 핵심 데이터 구조인 객체와 배열의 기초를 학습했습니다.

객체는 이름(키)과 값으로 이루어진 속성을 묶어 연관된 데이터를 구조화할 때 사용됩니다.

점 표기법과 대괄호 표기법으로 속성에 접근하고, 속성을 추가/변경/삭제하는 흐름을 확인했습니다.

객체 내부에 정의된 함수인 메서드의 개념도 함께 다뤘습니다.

배열은 순서(인덱스)를 기반으로 여러 값을 목록 형태로 저장하는 데 사용됩니다.

배열의 요소에 접근하고, push(), pop(), shift(), unshift(), splice()와 같은 다양한 메서드를 사용하여 요소를 추가하거나 제거하는 방법을 배웠습니다.

그리고 for, for...of, forEach()를 이용한 배열 순회 방법도 알아보았습니다.

이러한 객체와 배열은 실제 웹 개발에서 수많은 데이터를 다루는 데 있어 없어서는 안 될 도구입니다.

복잡한 데이터를 논리적으로 구성하고 처리하는 능력을 기르기 위해, 다양한 상황에서 객체와 배열을 활용해보는 연습을 꾸준히 수행해 데이터 처리 기준을 고정하는 것이 좋습니다.

객체 배열 데이터 구성

객체는 이름 있는 속성으로 한 대상을 설명하고, 배열은 순서 있는 값 묶음으로 목록 작업을 표현한다.

구성역할예시검토 질문
Object property대상의 속성을 이름으로 보관user.name속성 이름이 의미를 설명하는가
Array item같은 종류 값을 순서로 보관users[0]순서나 반복이 필요한가
Array of objects목록 안의 각 대상을 구조화users.map(user => ...)key로 식별 가능한가
Copy참조 공유를 피함{...obj}, [...arr]얕은 복사로 충분한가
Transform원하는 모양으로 새 데이터 생성map/filter/reduce원본 mutation을 피하는가