자바스크립트 - 데이터 구조 다루기: 모던 문법

hogu__giriboy·2026년 3월 4일

스프린트

목록 보기
5/13

1. 모던 자바스크립트 문법의 등장

이 파트의 핵심은 하나다.

ES6 이후 문법들은
코드를 예쁘게 만들기 위해 나온 것이 아니라

데이터와 함수를
더 구조적으로 다루기 위해 등장했다.

즉 모던 문법은 크게 두 방향으로 발전했다.

데이터 구조 다루기

데이터를 다루는 대표적인 문법으로
Rest, Spread, Destructuring이 있는데,

이 문법들은
데이터를 모으고,
데이터를 펼치고,
데이터를 꺼내는 방식을
훨씬 간결하게 만든다.

코드 표현 간결화

코드 표현을 간결하게 하는 대표적인 문법으로는
삼항 연산자, Optional Chaining, Template literal, 단축평가가 있는데,

이 문법들도 각각
조건 처리,
문자열 처리,
객체 접근 같은 반복적인 코드를 더 간결하게 만든다.

핵심 포인트

처음 보면 모던 자바스크립트 문법들은
각각 따로 노는 기능처럼 보인다.

하지만 구조적으로 보면 대부분은
"데이터를 다루는 방식"을 개선하기 위해 등장했다.

그래서 이번 파트에서 등장하는 문법들도 크게 보면

  • 함수 인자 처리
  • 데이터 구조 다루기
  • 코드 간결화

이 세 가지 흐름으로 묶을 수 있다.


2. 함수 인자 다루기

자바스크립트에서 함수는
기본적으로 입력을 받아서 동작한다.

이 입력을 처리하는 방식이
바로 함수 인자(parameter)다.

여기서 가장 먼저 구분해야 하는 게 있다.

Parameter / Argument

이 둘은 완전히 다른 개념이다.

Parameter (매개변수)

함수를 정의할 때 사용하는 변수

function greet(name) {
  console.log(name);
}

여기서 nameparameter다.

즉 "함수 내부에서 사용할 변수"를 지칭한다.

Argument (인자)

함수를 실제로 호출할 때 전달하는 값이다.

greet("홍길동");

여기서 "홍길동"argument다.

정리하면
Parameter는 "함수 정의에서 입력을 받기 위해 선언된 변수",
풀어서 입력을 받는 자리라고 볼 수 있다.
Argument는 "함수 호출 시 전달되는 실제 값(또는 표현식)",
풀어서 그 자리에 들어가는 실제 데이터라고 볼 수 있다.
예제를 같이 보면 더 명확하다.

function add(a, b) {
  // parameter
  return a + b;
}

add(10, 20); // argument

여기서 a,b가 parameter,
10, 20이 argument다.

핵심

자바스크립트 함수는 인자 개수를 강제하지 않는다.

function greet(name) {
  console.log(name);
}

greet();

결과는 undefined가 나온다.
왜냐하면 name에 전달된 argument가 없기 때문이다.
그래서 등장한 문법이 바로 다음에 나올 Default Parameter다.

Default Parameter

앞에서 봤듯이 자바스크립트 함수는
인자가 전달되지 않아도 에러가 나지 않는다.

function greet(name) {
  console.log(name);
}

greet();

이 경우 name에는 값이 없기 때문에
undefined가 출력된다.

그래서 예전에는 기본값을 직접 처리하는 코드를 많이 썼다.

function greet(name) {
  name = name || "Guest";
  console.log(name);
}

이 코드는 namefalsy"Guest" 사용 이라는 방식이다.

하지만 이 방식은 몇 가지 문제가 있다.

예를 들어

greet("");

처럼 빈 문자열을 전달해도 Guest가 되어버린다.
왜냐하면 빈 문자열도 falsy이기 때문이다.

같은 이유로 0도 falsy라서 의도와 다르게 기본값이 적용될 수 있다.

그래서 ES6에서 Default Parameter 문법이 등장했다.

function greet(name = "Guest") {
  console.log(name);
}

이제 인자가 전달되지 않으면 name = "Guest"가 자동으로 적용된다.

즉, greet();의 출력 결과는 "Guest"가 된다.

특징

Default Parameter는 "인자가 전달되지 않았을 때"만 동작한다.

즉 함수 정의에서

function add(a = 0, b = 0) {
  return a + b;
}

이렇게 작성하면 add(5);의 경우
a는 5, b는 0이 된다.

Default Parameter는 함수 매개변수에 기본값을 설정하는 문법이며
인자가 전달되지 않았을 때 자동으로 적용된다.

Rest Parameter

Default Parameter가 해결한 문제는 인자가 없을 때 기본값이었다.

하지만 함수에는 또 다른 상황이 있다.
이번에 다뤄볼 상황은
인자의 개수가 정해져 있지 않을 때다.

예를 들어 이런 함수다.

sum(1, 2, 3);
sum(10, 20, 30, 40);
sum(5, 6);

이처럼 몇 개의 인자가 전달될지 모르는 함수를 만들 때가 있다.

이 문제를 해결하기 위해 등장한 문법이
Rest Parameter다.

기본 문법

function sum(...numbers) {
  console.log(numbers);
}

sum(1, 2, 3);

출력은 [1, 2, 3]인데,
여기서 ...numbers가 Rest Parameter다.

이 문법은 "여러 개의 인자를 하나의 배열로 모은다"는 특징이 있다.

1, 2, 3numbers라는 배열로 모인다.

그래서 이름도 Rest(나머지) 다.

필요성

Rest Parameter가 등장하기 전에는
arguments라는 객체를 사용했다.

function sum() {
  console.log(arguments);
}

sum(1, 2, 3);

출력은 Arguments(3) [1, 2, 3]이지만
arguments에는 배열이 아니라 유사 배열 객체라는 문제가 있다.

그래서 map, filter, reduce라는
배열 메서드를 바로 사용할 수 없다.

이 문제를 해결하기 위해 ES6에서 Rest Parameter가 도입됐다.

특징

Rest Parameter로 받은 값은 실제 배열이다.

function sum(...numbers) {
  console.log(Array.isArray(numbers));
}

sum(1, 2, 3);

출력 결과는 true로 나온다.
그래서 배열 메서드를 자유롭게 사용할 수 있다.

Rest Parameter는 항상 마지막 매개변수여야 한다.

function test(a, ...rest) {}

이건 가능하지만

function test(...rest, a) {
}

이건 문법 오류다.
왜냐하면 Rest는 "남은 인자를 전부 모으는 문법"이기 때문이다.

핵심

Rest Parameter의 핵심은 여러 인자를 배열로 모으는 것이고, 다음의 Spread(펼치기)와 대칭이다.


3. 데이터를 펼치기

Rest Parameter가 여러 값을 하나로 모으는 문법이라면,
Spread는 묶여 있는 데이터를 개별 요소로 풀어내는 문법이다.

Spread

Spread는 ... 문법을 사용한다.

const numbers = [1, 2, 3];

console.log(...numbers);

출력 결과는 1 2 3이 된다.
배열이었던 [1, 2, 3]개별 값으로 펼쳐진다.

배열에서의 Spread

Spread는 배열을 다른 배열과 쉽게 합칠 때 자주 사용된다.

예전 방식이

const arr1 = [1, 2];
const arr2 = [3, 4];

const result = arr1.concat(arr2);

이었다면, 이젠 Spread를 사용하여

const arr1 = [1, 2];
const arr2 = [3, 4];

const result = [...arr1, ...arr2];

결과는 [1, 2, 3, 4]를 낸다.

즉, 배열을 펼쳐서 새로운 배열에 넣는 방식이라고 이해하면 된다.

배열 복사

Spread는 배열 복사에도 많이 사용된다.

const arr1 = [1, 2, 3];
const arr2 = [...arr1];

결과는 arr2[1, 2, 3]이 된다.

이 방식은 얕은 복사(shallow copy) 를 만들 때 자주 사용된다.

객체에서의 Spread

Spread는 객체에서도 사용할 수 있다.

const person = {
  name: "홍길동",
  age: 25,
};

const newPerson = {
  ...person,
  job: "developer",
};

결과는

{
  name: "홍길동",
  age: 25,
  job: "developer"
}

즉 객체에서도 기존 속성을 펼쳐서
새 객체에 넣을 수 있다.

핵심

Spread의 핵심은 딱 하나다.
Spread는 묶여 있는 데이터를 펼치는 문법이라는 것이며,
대표적으로 배열 합치기, 배열 복사, 객체 확장에서 사용된다.

그리고 이 개념은 이전에 배운
데이터를 모으는 Rest와 반대로
데이터를 펼치는 역할을 하므로 서로 대칭 관계를 가진다.

Rest vs Spread

동일한 형태

Rest와 Spread는 ...으로 문법이 완전히 동일하다.

그래서 처음 보면 같은 기능처럼 보이지만
실제로는 완전히 반대 역할을 한다.

앞에서 다뤘지만, 비교를 통해 다시 간단히 정리해보자.

Rest: 모으기

Rest Parameter는 여러 개의 인자를 하나의 배열로 모은다.

function sum(...numbers) {
  console.log(numbers);
}

sum(1, 2, 3);

출력 결과로 [1, 2, 3]이 나온다.

즉 여러 값을 하나의 배열로 모으는 역할을 한다.

Spread: 펼치기

Spread는 묶여 있는 데이터를 개별 값으로 펼친다.

const numbers = [1, 2, 3];

console.log(...numbers);

출력 결과로 1 2 3이 나온다.

즉 배열을 개별 값으로 풀어내는 역할을 한다.

핵심

문법역할방향
Rest여러 값을 하나로 모음모으기
Spread묶인 데이터를 펼침펼치기

같은 ... 문법이지만
함수 매개변수는 Rest,
배열/객체/함수 호출에서는 Spread로 사용된다.

즉 같은 문법이지만 사용되는 위치에 따라 Rest와 Spread의 의미가 달라진다.


4. 데이터를 꺼내기

지금까지 우리는 데이터를 다루는 두 가지 방식을 봤다.

  • Rest → 여러 값을 모은다.
  • Spread → 묶인 데이터를 펼친다.

이번에는 그 다음 단계다.

  • Destructuring → 구조를 기준으로 값을 꺼낸다.

Destructuring은
배열이나 객체에 담긴 값을 구조를 기준으로 꺼내 변수에 할당하는 문법이다.

배열 Destructuring

기존 방식

배열에서 값을 꺼내려면 보통 인덱스 를 사용한다.

const numbers = [1, 2, 3];

const a = numbers[0];
const b = numbers[1];

이 방식은 배열의 위치를 직접 기억해야 한다는 문제가 있다.
코드도 길어진다.

배열 Destructuring

Destructuring을 사용하면
배열 구조를 기준으로 바로 값을 꺼낼 수 있다.

이 문법은 배열의 구조를 변수 구조에 그대로 맞춰 값을 할당 한다.

예를 들어

const numbers = [1, 2, 3];

const [a, b, c] = numbers;

결과

a → 1
b → 2
c → 3

즉 배열의 순서를 기준으로 값이 할당된다.

값 건너뛰기

특정 값만 꺼내고 싶을 때도 있다.

const numbers = [1, 2, 3];

const [first, , third] = numbers;

결과

first → 1
third → 3

중간 값을 건너뛸 수 있다.

기본값

배열에 값이 없을 때 기본값을 줄 수도 있다.

const numbers = [1];

const [a, b = 10] = numbers;

결과

a → 1
b → 10

Rest와 함께 사용

배열 Destructuring에서도 Rest를 사용할 수 있다.

const numbers = [1, 2, 3, 4];

const [first, ...rest] = numbers;

결과

first → 1
rest → [2, 3, 4]

객체 Destructuring

기존 방식

객체에서 값을 꺼낼 때는
보통 프로퍼티 이름으로 접근한다.

const user = {
  name: "홍길동",
  age: 25,
};

const name = user.name;
const age = user.age;

하지만 이 방식도 코드가 길어진다.

객체 Destructuring

Destructuring을 사용하면
객체의 속성 이름을 기준으로 값을 꺼낼 수 있다.

const user = {
  name: "홍길동",
  age: 25,
};

const { name, age } = user;

결과

name → "홍길동"
age → 25

배열과 달리 객체는
순서가 아니라 속성 이름을 기준으로 값이 할당된다.

이름 변경 (alias)

변수 이름을 다르게 지정할 수도 있다.

const user = {
  name: "홍길동",
  age: 25,
};

const { name: username } = user;

결과

username → "홍길동"

즉 객체 속성 이름을 다른 변수 이름으로 할당할 수 있다.

함수 매개변수 Destructuring

지금까지 우리는 Destructuring을 이용해
배열이나 객체에서 값을 꺼내는 방법을 봤다.

이 문법은 함수의 매개변수에서도 사용할 수 있다.

기존 방식

객체를 함수에 전달하면
보통 이렇게 접근한다.

function printUser(user) {
  console.log(user.name);
  console.log(user.age);
}

const user = {
  name: "홍길동",
  age: 25,
};

printUser(user);

이 방식은 객체 이름을 계속 반복해서 사용해야 한다는 문제가 있다.

매개변수 Destructuring

함수 매개변수에서 바로 구조 분해를 사용할 수 있다.

function printUser({ name, age }) {
  console.log(name);
  console.log(age);
}

const user = {
  name: "홍길동",
  age: 25,
};

printUser(user);

결과

name → "홍길동"
age → 25

즉 객체의 속성을 함수 매개변수에서 바로 꺼낼 수 있다.

핵심

함수 매개변수 Destructuring은
객체를 전달받을 때
필요한 값만 바로 꺼내 사용할 수 있는 문법이다.

그래서 코드가 더 짧아지고 가독성이 좋아진다.


5. 객체 문법 간단히 쓰기

JavaScript에서는 객체를 만들 때
보통 key: value 형태로 작성한다.

모던 프로퍼티 표기법

기존 방식

const name = "홍길동";
const age = 25;

const user = {
  name: name,
  age: age,
};

이 방식은 변수 이름과 객체 속성 이름이 같아도
두 번 작성해야 하는 문제가 있다.
그래서 코드가 불필요하게 길어진다.

모던 프로퍼티 표기법

ES6에서는 이를 간단하게 작성할 수 있는
모던 프로퍼티 표기법이 도입됐다.

const user = {
  name,
  age,
};

이 문법은 변수 이름과 객체 속성 이름이 같을 때
속성 이름만 작성하면 값이 자동으로 할당된다.

결과적으로

{
  name: "홍길동",
  age: 25
}

와 동일한 객체가 생성된다.

핵심

모던 프로퍼티 표기법은 변수 이름과 객체 속성 이름이 같을 때
속성 이름만 작성하는 문법이다.

그래서 코드가 더 짧아지고 더 읽기 쉬워진다.


6. 코드를 간결하게

지금까지 살펴본 모던 자바스크립트 문법들은
대부분 코드를 더 간결하게 작성하기 위해 등장했다.

이 파트에서는 조건 처리나 객체 접근처럼
자주 사용하는 코드를 더 짧게 작성하는 문법을 살펴본다.

삼항 연산자

삼항 연산자는 조건에 따라 두 가지 값 중 하나를 선택하는 연산자다.

기본 형태

조건 ?1 :2;

조건이 true값1이 반환되고
조건이 false값2가 반환된다.

기존 방식

조건문을 사용하면 보통 이렇게 작성한다.

const score = 75;

let result;

if (score >= 60) {
  result = "합격";
} else {
  result = "불합격";
}

이 방식은 코드가 길어질 수 있다.

삼항 연산자 사용

삼항 연산자를 사용하면 같은 코드를 더 간단하게 작성할 수 있다.

const result = score >= 60 ? "합격" : "불합격";

이처럼 간단한 조건 분기에서는
삼항 연산자를 사용하면 코드가 더 간결해진다.

Optional Chaining

객체의 속성에 접근할 때
존재하지 않는 값에 접근하면 오류가 발생할 수 있다.

예를 들어

const user = {};

console.log(user.profile.name);

이 경우 profile이 존재하지 않기 때문에
에러가 발생한다.

기존 방식

그래서 보통 이런 방식으로 확인한다.

if (user.profile) {
  console.log(user.profile.name);
}

또는

const name = user.profile && user.profile.name;

하지만 이 방식도 코드가 길어질 수 있다.

Optional Chaining

Optional Chaining을 사용하면
이 과정을 더 간단하게 작성할 수 있다.

const name = user.profile?.name;

이 문법은 앞의 값이 null 또는 undefined가 아닐 때만 다음 속성에 접근한다.
그래서 profile이 없으면 에러가 발생하지 않고
결과는 undefined가 된다.

하지만 Optional Chaining은 문제를 해결하기보다는
오류 상황을 숨길 수 있으므로 무분별하게 사용하는 것은 지양하는 것이 좋다.

Template literal

Template literal은 문자열을 더 편하게 작성하기 위한 문법이다.

기존에는 문자열을 연결할 때 보통 + 연산자를 사용했다.

기존 방식

const name = "홍길동";
const age = 25;

const message = "이름은 " + name + "이고 나이는 " + age + "입니다.";

이 방식은 문자열과 변수를 계속 연결해야 해서
코드가 복잡해질 수 있다.

Template literal

Template literal을 사용하면 문자열 안에서
변수를 직접 삽입할 수 있다.

const name = "홍길동";
const age = 25;

const message = `이름은 ${name}이고 나이는 ${age}입니다.`;

이 문법은 ${변수} 형태로 문자열 안에 값을 삽입한다.

그래서 코드가 더 읽기 쉬워진다.

단축 평가

JavaScript에서는 논리 연산자를 이용해
조건에 따라 값을 간단하게 선택할 수 있다.

기본 형태

A && B;

Atruthy일 때 B가 반환된다.

A || B;

Afalsy일 때 B가 반환된다.

예시

const user = {
  name: "홍길동",
};

const name = user && user.name;

이 코드는 user가 존재하면 user.name 반환한다는 의미다.

기본값 설정

단축 평가는 기본값 설정에도 자주 사용된다.

const name = input || "Guest";

이 코드는 input 값이 falsy"Guest" 사용이라는 의미다.


7. 핵심 정리

모던 자바스크립트 문법은
단순히 코드를 짧게 만들기 위해 등장한 것이 아니다.

대부분의 문법은 데이터를 더 구조적으로 다루기 위해 등장했다.

지금까지 살펴본 문법들을 정리하면 다음과 같이 묶을 수 있다.

함수 인자 처리

Default Parameter

인자가 전달되지 않았을 때 기본값을 설정한다.

Rest Parameter

여러 개의 인자를 하나의 배열로 모은다.

데이터 구조 다루기

Spread

묶여 있는 배열이나 객체를 펼친다.

Destructuring

배열이나 객체의 구조를 기준으로 값을 꺼낸다.

코드 표현 간결화

Template literal

문자열 안에서 변수를 쉽게 삽입할 수 있다.

삼항 연산자

간단한 조건 분기를 한 줄로 표현할 수 있다.

Optional Chaining

앞의 값이 null 또는 undefinedundefined를 반환한다.

단축 평가

논리 연산자를 이용해 조건에 따라 값을 선택할 수 있다.
논리 연산자는 true/false가 아니라 값 자체를 반환한다.

정리

모던 자바스크립트 문법은
새로운 기능을 추가하기보다는
데이터를 모으고, 펼치고, 꺼내고
코드를 간결하게 표현하는 방식을 개선하는 데
초점이 맞춰져 있다.

그래서 각 문법을 따로 외우기보다는
데이터를 다루는 흐름 속에서 이해하는 것이 중요하다.

0개의 댓글