Skip to main content
Summary

여러 값을 하나씩 따로 두면 금방 복잡해집니다

상품 이름이 하나뿐이라면 변수 하나로 충분합니다.

const productName = '노트북';

그런데 장바구니에 상품이 세 개라면 어떨까요?

const product1 = '노트북';
const product2 = '마우스';
const product3 = '키보드';

처음에는 괜찮아 보입니다. 하지만 상품이 10개, 100개가 되면 변수 이름을 계속 만들어야 합니다. 전체 상품을 반복문으로 확인하기도 어렵습니다.

이럴 때 사용하는 것이 배열입니다. 배열은 여러 값을 순서대로 담는 목록입니다.

const cart = ['노트북', '마우스', '키보드'];

console.log(cart);

배열은 대괄호 []로 만들고, 값과 값은 쉼표로 구분합니다. 장바구니, 참석자 명단, 할 일 목록, 점수 목록처럼 "여러 개가 줄지어 있는 데이터"에 잘 어울립니다.

목록은 배열로, 묶음 정보는 객체로 다루기AI 생성 이미지

배열의 순서는 0번부터 시작합니다

배열에서 각 값의 위치를 인덱스라고 부릅니다. 인덱스는 목록 안의 좌석 번호처럼 생각하면 됩니다. 다만 자바스크립트의 좌석 번호는 1번이 아니라 0번부터 시작합니다.

const seats = ['민지', '준호', '서연'];

console.log(seats[0]); // 민지
console.log(seats[1]); // 준호
console.log(seats[2]); // 서연

첫 번째 값은 seats[1]이 아니라 seats[0]입니다. 이 부분은 초보자가 자주 헷갈립니다.

배열에 몇 개의 값이 들어 있는지는 length로 확인합니다.

const attendees = ['민지', '준호', '서연'];

console.log(attendees.length); // 3

마지막 값의 인덱스는 항상 length - 1입니다.

console.log(attendees[attendees.length - 1]); // 서연

attendees[3]을 출력하면 네 번째 값을 찾습니다. 하지만 이 배열에는 네 번째 값이 없으므로 undefined가 나옵니다. 이것은 "그 자리에 값이 없다"는 뜻입니다.

장바구니에 넣고 빼기: push와 pop

배열은 목록이기 때문에 새 값을 추가하거나 마지막 값을 뺄 수 있습니다.

push()는 배열의 끝에 값을 추가합니다.

const cart = ['노트북', '마우스'];

cart.push('키보드');

console.log(cart); // ['노트북', '마우스', '키보드']

pop()은 배열의 마지막 값을 꺼냅니다.

const cart = ['노트북', '마우스', '키보드'];

const removedItem = cart.pop();

console.log(removedItem); // 키보드
console.log(cart); // ['노트북', '마우스']

여기서 중요한 점이 있습니다. push()와 pop()은 원본 배열을 직접 바꿉니다.

const cart = ['노트북'];

cart.push('마우스');

console.log(cart); // ['노트북', '마우스']

const로 만든 배열인데 값이 바뀌었습니다. 이상해 보일 수 있습니다. const는 변수 이름이 다른 배열을 가리키도록 바꾸는 것을 막습니다. 하지만 그 배열 안의 내용까지 모두 얼려 두는 것은 아닙니다.

const cart = ['노트북'];

cart.push('마우스'); // 가능
// cart = ['키보드']; // 오류

초보 단계에서는 이렇게 기억하면 됩니다. const 배열도 안의 항목은 바뀔 수 있습니다.

명단에서 위치 찾기: indexOf

참석자 명단에 어떤 사람이 있는지 확인하고 싶을 때 indexOf()를 사용할 수 있습니다.

const attendees = ['민지', '준호', '서연'];

console.log(attendees.indexOf('준호')); // 1
console.log(attendees.indexOf('지훈')); // -1

indexOf()는 찾은 값의 인덱스를 돌려줍니다. 값이 없으면 -1을 돌려줍니다.

이 특징은 조건문과 함께 자주 씁니다.

const attendees = ['민지', '준호', '서연'];
const name = '지훈';

if (attendees.indexOf(name) === -1) {
  console.log('명단에 없습니다.');
} else {
  console.log('명단에 있습니다.');
}

여기서 === -1은 "찾지 못했다면"이라는 뜻으로 읽으면 됩니다.

배열을 하나씩 확인하기: forEach

배열의 모든 값을 한 번씩 출력하고 싶다면 반복문을 쓸 수 있습니다. 배열에는 더 편하게 사용할 수 있는 forEach()도 있습니다.

const attendees = ['민지', '준호', '서연'];

attendees.forEach(function (name) {
  console.log(name + '님, 참석 확인되었습니다.');
});

forEach()는 배열의 값을 앞에서부터 하나씩 꺼내 함수에 넣어 줍니다. 위 코드에서 name은 배열에서 하나씩 꺼낸 값이 잠시 들어오는 자리입니다.

실행 흐름은 이렇게 볼 수 있습니다.

// 첫 번째: name = '민지'
// 두 번째: name = '준호'
// 세 번째: name = '서연'

forEach()는 "각 항목마다 어떤 일을 하라"는 상황에 잘 어울립니다. 예를 들어 참석 안내 문자를 출력하거나, 상품 이름을 하나씩 화면에 보여 주는 일입니다.

다만 forEach()는 새 배열을 만들어 주는 도구가 아닙니다. 출력하거나, 확인하거나, 어떤 동작을 반복할 때 사용합니다.

필요한 항목만 고르기: filter

배열에서 조건에 맞는 값만 골라 새 배열을 만들고 싶을 때는 filter()를 사용합니다.

예를 들어 점수 목록에서 80점 이상만 고르겠습니다.

const scores = [60, 85, 90, 72, 100];

const passedScores = scores.filter(function (score) {
  return score >= 80;
});

console.log(passedScores); // [85, 90, 100]
console.log(scores); // [60, 85, 90, 72, 100]

filter() 안의 함수는 각 값에 대해 true 또는 false를 돌려줍니다. true가 나온 값만 새 배열에 남습니다.

중요한 점은 filter()가 원본 배열을 바꾸지 않는다는 것입니다. 위 코드에서 scores는 그대로입니다. 조건에 맞는 값만 담은 passedScores라는 새 배열이 만들어졌습니다.

장바구니에서 특정 상품을 제외할 때도 사용할 수 있습니다.

const cart = ['노트북', '마우스', '키보드'];

const newCart = cart.filter(function (item) {
  return item !== '마우스';
});

console.log(newCart); // ['노트북', '키보드']
console.log(cart); // ['노트북', '마우스', '키보드']

item !== '마우스'는 "마우스가 아닌 항목만 남긴다"는 뜻입니다.

값을 다른 모양으로 바꾸기: map

map()은 배열의 각 값을 바꿔서 새 배열을 만들 때 사용합니다.

const prices = [10000, 20000, 30000];

const salePrices = prices.map(function (price) {
  return price * 0.9;
});

console.log(salePrices); // [9000, 18000, 27000]
console.log(prices); // [10000, 20000, 30000]

map()도 원본 배열을 바꾸지 않습니다. 각 값을 계산한 결과로 새 배열을 만듭니다.

문자열을 안내 문구로 바꿀 수도 있습니다.

const attendees = ['민지', '준호', '서연'];

const messages = attendees.map(function (name) {
  return name + '님 환영합니다.';
});

console.log(messages);
// ['민지님 환영합니다.', '준호님 환영합니다.', '서연님 환영합니다.']

forEach()와 map()은 비슷해 보이지만 목적이 다릅니다.

  • forEach()는 각 항목마다 일을 실행합니다.

  • map()은 각 항목을 바꿔 새 배열을 만듭니다.

새 배열이 필요하면 map()을 고르고, 단순히 하나씩 출력하거나 처리하면 forEach()를 고르면 됩니다.

객체는 한 사람 또는 한 상품의 정보 카드입니다

배열은 순서가 있는 목록입니다. 그런데 실제 데이터는 값 하나만으로 끝나지 않는 경우가 많습니다.

상품 하나에는 이름, 가격, 재고가 함께 있습니다.

const productName = '무선 마우스';
const productPrice = 25000;
const productStock = 12;

이렇게 따로 두면 이 세 값이 같은 상품의 정보라는 사실이 코드만 보고는 약하게 드러납니다. 이럴 때 객체를 사용합니다.

객체는 관련 있는 정보를 한 장의 카드처럼 묶는 방식입니다.

const product = {
  name: '무선 마우스',
  price: 25000,
  stock: 12
};

console.log(product);

객체는 중괄호 {}로 만들고, 이름: 값 형태로 정보를 적습니다. 여기서 name, price, stock 같은 이름을 속성이라고 부릅니다.

속성 값을 꺼낼 때는 점 표기법을 많이 씁니다.

console.log(product.name); // 무선 마우스
console.log(product.price); // 25000
console.log(product.stock); // 12

대괄호 표기법도 사용할 수 있습니다.

console.log(product['name']); // 무선 마우스

대괄호 표기법은 속성 이름이 변수에 들어 있을 때 유용합니다.

const key = 'price';

console.log(product[key]); // 25000

처음에는 점 표기법을 기본으로 쓰고, 속성 이름을 변수로 다뤄야 할 때 대괄호 표기법을 쓰면 됩니다.

배열 안에 객체를 넣으면 실제 데이터와 가까워집니다

실제 업무 데이터는 대부분 배열과 객체가 함께 사용됩니다.

상품 하나는 객체입니다.

const product = {
  name: '무선 마우스',
  price: 25000,
  stock: 12
};

상품 목록은 이런 객체들이 들어 있는 배열입니다.

const products = [
  { name: '무선 마우스', price: 25000, stock: 12 },
  { name: '키보드', price: 45000, stock: 5 },
  { name: '모니터', price: 180000, stock: 0 }
];

이 구조는 처음 보면 길어 보입니다. 하지만 읽는 방법은 단순합니다.

  • products는 상품 목록입니다.

  • 목록의 각 항목은 상품 하나입니다.

  • 상품 하나에는 name, price, stock이 있습니다.

첫 번째 상품 이름을 꺼내 보겠습니다.

console.log(products[0].name); // 무선 마우스

읽는 순서는 왼쪽에서 오른쪽입니다.

  1. products[0]으로 첫 번째 상품 객체를 꺼냅니다.

  2. .name으로 그 상품의 이름을 꺼냅니다.

재고가 있는 상품만 고를 수도 있습니다.

const availableProducts = products.filter(function (product) {
  return product.stock > 0;
});

console.log(availableProducts);

가격만 모아 새 배열을 만들 수도 있습니다.

const prices = products.map(function (product) {
  return product.price;
});

console.log(prices); // [25000, 45000, 180000]

상품 이름만 안내 문구로 바꿀 수도 있습니다.

const labels = products.map(function (product) {
  return product.name + ' - ' + product.price + '원';
});

console.log(labels);

특정 상품 하나를 찾고 싶다면 find()를 사용할 수 있습니다.

const keyboard = products.find(function (product) {
  return product.name === '키보드';
});

console.log(keyboard);

find()는 조건에 맞는 첫 번째 항목을 돌려줍니다. 조건에 맞는 항목이 없으면 undefined가 나옵니다.

const tablet = products.find(function (product) {
  return product.name === '태블릿';
});

console.log(tablet); // undefined

따라서 찾은 결과를 바로 사용하기 전에 조건문으로 확인하면 안전합니다.

if (tablet === undefined) {
  console.log('상품을 찾지 못했습니다.');
}

원본을 바꾸는지, 새 배열을 만드는지 구분합니다

배열을 다룰 때 초보자가 자주 만나는 문제가 있습니다. "분명 새로 만든다고 생각했는데 원본이 바뀌었다"는 상황입니다.

메서드마다 성격이 다릅니다.

  • push()는 원본 배열에 값을 추가합니다.

  • pop()은 원본 배열에서 마지막 값을 뺍니다.

  • filter()는 조건에 맞는 값으로 새 배열을 만듭니다.

  • map()은 값을 바꾼 새 배열을 만듭니다.

  • forEach()는 새 배열을 만들지 않고 각 항목을 처리합니다.

  • indexOf()는 값의 위치를 알려 주고 원본을 바꾸지 않습니다.

작은 예제로 확인해 보겠습니다.

const items = ['A', 'B'];

const result = items.push('C');

console.log(items); // ['A', 'B', 'C']
console.log(result); // 3

push()의 결과는 새 배열이 아니라 배열의 길이입니다. 그래서 아래처럼 쓰면 기대와 다르게 동작합니다.

const items = ['A', 'B'];
const newItems = items.push('C');

console.log(newItems); // 3

새 배열을 만들고 싶다면 나중에 더 다양한 방법을 배울 수 있습니다. 지금은 우선 "push()는 원본을 바꾼다"는 사실을 기억하면 충분합니다.

반대로 filter()는 새 배열을 만듭니다.

const items = ['A', 'B', 'C'];

const filteredItems = items.filter(function (item) {
  return item !== 'B';
});

console.log(items); // ['A', 'B', 'C']
console.log(filteredItems); // ['A', 'C']

원본을 직접 바꿔도 되는 상황인지, 원본은 그대로 두고 새 배열이 필요한 상황인지 먼저 생각하면 예상 밖 변경을 줄일 수 있습니다.

작은 실습: 품절 상품을 제외하고 가격표 만들기

아래 코드를 브라우저 콘솔에 그대로 입력해 보세요.

const products = [
  { name: '무선 마우스', price: 25000, stock: 12 },
  { name: '키보드', price: 45000, stock: 5 },
  { name: '모니터', price: 180000, stock: 0 },
  { name: 'USB 케이블', price: 8000, stock: 30 }
];

const availableProducts = products.filter(function (product) {
  return product.stock > 0;
});

const priceLabels = availableProducts.map(function (product) {
  return product.name + ': ' + product.price + '원';
});

priceLabels.forEach(function (label) {
  console.log(label);
});

이 코드는 세 단계로 움직입니다.

  1. filter()로 재고가 있는 상품만 고릅니다.

  2. map()으로 상품 객체를 가격표 문장으로 바꿉니다.

  3. forEach()로 가격표를 하나씩 출력합니다.

배열과 객체를 함께 쓰면 데이터가 훨씬 실제 업무에 가까워집니다. 장바구니는 배열이고, 장바구니 안의 상품 하나는 객체입니다. 참석자 명단은 배열이고, 참석자 한 명의 이름·이메일·참석 여부는 객체입니다. 일정표는 배열이고, 일정 하나의 제목·날짜·장소는 객체입니다.

앞으로 웹페이지를 직접 바꿀 때도 이 구조를 자주 만나게 됩니다. 화면에 보여 줄 데이터는 대개 배열과 객체로 준비해 두고, 자바스크립트가 그 데이터를 읽어 HTML 화면으로 바꿔 줍니다.

책 목록

비개발자를 위한 JavaScript: 설치 없이 시작해 작은 프로젝트까지

전체 목차 보기

이 노트는 보도·비평·교육·연구 목적으로 작성되었습니다. 저작권 문의가 있으시면 에서 알려주세요.

틸노트는 사용자가 AI를 활용해 노트를 쉽게 작성하거나 편집할 수 있는 서비스입니다.

AI 스퀘어 단톡방에 함께해요

AI 활용과 틸노트 사용 팁을 나누는 오픈채팅방입니다. 입장 비밀번호는 tilnote입니다.

참여하기