Type something to search...

01 필수 JavaScript 문법

1. 변수 선언: let, const

var 대신 let과 const를 사용합니다. React에서는 주로 const를 사용합니다.

예제 1: let과 const의 차이

  let age = 20;                   // let: 재할당 가능한 변수
  age = 21;                       // 값 변경 가능
  console.log(age);               // 21 출력

  const name = '철수';            // const: 재할당 불가능한 상수
  // name = '영희';               // 오류 발생! const는 재할당 불가

  const arr = [1, 2, 3];          // const 배열
  arr.push(4);                    // 배열 내용 변경은 가능
   console.log(arr);              // [1, 2, 3, 4]
   // arr = [5, 6];               // 오류! 배열 자체를 재할당은 불가

핵심: const는 변수의 재할당을 막지만, 객체나 배열의 내용 변경은 가능합니다.


2. 화살표 함수 (Arrow Function, 애로우 펑션)

함수를 더 짧게 작성하는 방법입니다. React에서 매우 자주 사용됩니다.

예제 2: 일반 함수 vs 화살표 함수

// 일반 함수
function add1(a, b) {           // function 키워드 사용
  return a + b;                 // return 명시
}
// 화살표 함수 - 기본형
const add2 = (a, b) => {        // => 사용
  return a + b;                 // return 명시
};

 // 화살표 함수 - 간단한 형태
 const add3 = (a, b) => a + b;  // 한 줄이면 return과 중괄호 생략 가능

 // 매개변수가 하나일 때
 const double = x => x * 2;     // 소괄호도 생략 가능

 // 매개변수가 없을 때
 const greet = () => '안녕';    // 소괄호 필수

 console.log(add3(5, 3));       // 8
 console.log(double(4));        // 8

예제 3: 화살표 함수와 this

const user = {
  name: '철수',
  sayHi1: function() {           // 일반 함수
    console.log('안녕 ' + this.name); // this는 user 객체
  },
  sayHi2: () => {                 // 화살표 함수
    console.log('안녕 ' + this.name); // this는 상위 스코프의 this
  }
};

 user.sayHi1();                   // '안녕 철수'
 user.sayHi2();                   // '안녕 undefined' (React에서는 class component에서 주의)

3. 템플릿 리터럴 (Template Literal, 템플릿 리터럴)

백틱(`)을 사용해 문자열을 만들고, $ 안에 변수나 표현식을 넣을 수 있습니다.

예제 4: 템플릿 리터럴 활용

const name = '철수';
const age = 20;
// 기존 방식
const msg1 = '이름: ' + name + ', 나이: ' + age; // 문자열 연결
// 템플릿 리터럴
const msg2 = `이름: ${name}, 나이: ${age}`;      // 백틱과 ${} 사용
 // 표현식 사용 가능
 const msg3 = `내년 나이: ${age + 1}세`;         // 계산식 가능

 // 여러 줄 문자열
 const html = `
   <div>
     <h1>${name}</h1>
     <p>${age}세</p>
   </div>
 `;                                              // 여러 줄 작성 가능

 console.log(msg2);                             // 이름: 철수, 나이: 20

4. 구조 분해 할당 (Destructuring, 디스트럭처링)

배열이나 객체의 값을 쉽게 추출합니다. React Props와 State에서 필수입니다.

//객체 구조 분해
const user = {
  name: '철수',
  age: 20,
  job: '개발자'
};
// 기존 방식
const name1 = user.name;        // 하나씩 추출
const age1 = user.age;

 // 구조 분해 할당
 const { name, age, job } = user; // 한 번에 추출
 console.log(name);               // '철수'
 console.log(age);                // 20

 // 변수명 변경
 const { name: userName, age: userAge } = user; // 다른 이름으로 추출
 console.log(userName);           // '철수'

 // 기본값 설정
 const { name, city = '서울' } = user; // city가 없으면 '서울' 사용
 console.log(city);               // '서울'


//배열 구조 분해
 const arr = [1, 2, 3, 4, 5];
// 기존 방식
const first1 = arr[0];           // 인덱스로 접근
const second1 = arr[1];
// 구조 분해 할당
const [first, second] = arr;     // 순서대로 추출
console.log(first);               // 1
 console.log(second);              // 2

 // 일부만 추출
 const [a, , c] = arr;             // 중간 값 건너뛰기 (쉼표로)
 console.log(a, c);                // 1 3

 // 나머지 요소
 const [x, ...rest] = arr;         // 첫 번째 제외하고 나머지
 console.log(rest);                // [2, 3, 4, 5]
  // 함수 매개변수에서 구조 분해 (React Props에서 자주 사용)
 // 기존 방식
 function greet1(user) {           // 객체를 통째로 받음
   console.log(`안녕 ${user.name}`);
 }

 // 구조 분해 활용
 function greet2({ name, age }) {  // 필요한 속성만 추출
   console.log(`안녕 ${name}, ${age}세`);
 }

 const user = { name: '철수', age: 20 };
 greet2(user);                     // 안녕 철수, 20세

5. 스프레드 연산자 (Spread Operator, 스프레드 오퍼레이터)

… 을 사용해 배열이나 객체를 펼칩니다. React에서 불변성 유지에 필수입니다.

예제 8: 배열 스프레드

const arr1 = [1, 2, 3];
const arr2 = [4, 5, 6];
// 배열 합치기
const arr3 = [...arr1, ...arr2];  // arr1과 arr2를 펼쳐서 합침
console.log(arr3);                // [1, 2, 3, 4, 5, 6]
// 배열 복사
const copy = [...arr1];           // 새로운 배열 생성 (원본 유지)
 copy.push(4);                     // 복사본만 변경
 console.log(arr1);                // [1, 2, 3] (원본 그대로)
 console.log(copy);                // [1, 2, 3, 4]

 // 요소 추가
 const arr4 = [0, ...arr1, 4];     // 앞뒤로 요소 추가 가능
 console.log(arr4);                // [0, 1, 2, 3, 4]

예제 9: 객체 스프레드

const user = { name: '철수', age: 20 };
// 객체 복사
const copy = { ...user };         // 새로운 객체 생성
// 속성 추가
const user2 = { ...user, job: '개발자' }; // 기존 속성 + 새 속성
console.log(user2);               // { name: '철수', age: 20, job: '개발자' }
 // 속성 덮어쓰기
 const user3 = { ...user, age: 21 }; // age만 변경
 console.log(user3);               // { name: '철수', age: 21 }

 // 여러 객체 합치기
 const a = { x: 1, y: 2 };
 const b = { y: 3, z: 4 };
 const c = { ...a, ...b };         // y는 b의 값으로 덮어써짐
 console.log(c);                   // { x: 1, y: 3, z: 4 }

6. 배열 메서드 (Array Methods, 어레이 메서드)

React에서 리스트 렌더링에 필수적인 배열 메서드들입니다.

예제 10: map - 배열 변환 (가장 중요!)

const nums = [1, 2, 3, 4, 5];
// 각 요소에 2를 곱한 새 배열
const doubled = nums.map(num => num * 2); // 각 요소를 변환
console.log(doubled);             // [2, 4, 6, 8, 10]
// 객체 배열 변환
const users = [
  { id: 1, name: '철수' },
   { id: 2, name: '영희' }
 ];

 const names = users.map(user => user.name); // name만 추출
 console.log(names);               // ['철수', '영희']

 // HTML 문자열 생성 (React와 유사)
 const items = nums.map(num => `<li>${num}</li>`); // 각 숫자를 li로 변환
 console.log(items);               // ['<li>1</li>', '<li>2</li>', ...]

예제 11: forEach - 배열 순회 (반환값 없음)

const nums = [1, 2, 3, 4, 5];
// forEach는 반환값이 없음 (undefined 반환)
const result1 = nums.forEach(num => {
  console.log(num);               // 1, 2, 3, 4, 5 출력
});
console.log(result1);             // undefined
// 외부 변수 수정 (부수 효과)
 let sum = 0;
 nums.forEach(num => {
   sum += num;                     // 외부 변수 변경
 });
 console.log(sum);                 // 15

 // map은 새 배열 반환
 const result2 = nums.map(num => num * 2);
 console.log(result2);             // [2, 4, 6, 8, 10]

예제 12: map vs forEach 비교

const nums = [1, 2, 3];
// map: 새 배열 생성 (React 렌더링에 사용)
const doubled = nums.map(num => num * 2); // 새 배열 반환
console.log(doubled);             // [2, 4, 6]
// forEach: 반복만 수행 (로깅, 부수효과에 사용)
nums.forEach(num => {
  console.log(num * 2);           // 2, 4, 6 출력 (반환값 없음)
 });

 // 잘못된 사용 예시
 const wrong = nums.forEach(num => num * 2); // 의미 없음
 console.log(wrong);               // undefined

 // 올바른 사용
 // map: 데이터 변환이 필요할 때
 const newArr = nums.map(num => ({ value: num })); // 객체 배열로 변환

 // forEach: 단순 반복 작업
 nums.forEach((num, idx) => {
   console.log(`${idx}: ${num}`); // 인덱스와 함께 출력
 });

예제 13: map과 forEach 실전 비교

const users = [
  { id: 1, name: '철수', active: true },
  { id: 2, name: '영희', active: false },
  { id: 3, name: '민수', active: true }
];
// React에서 사용: map으로 JSX 배열 생성
const userList = users.map(user => `<li>${user.name}</li>`);
console.log(userList);             // ['<li>철수</li>', '<li>영희</li>', '<li>민수</li>']

 // 단순 출력: forEach 사용
 console.log('=== 사용자 목록 ===');
 users.forEach(user => {
   console.log(`${user.id}. ${user.name}`); // 콘솔 출력만
 });

 // 체이닝 가능 여부
 const activeNames = users
   .filter(user => user.active)    // map은 체이닝 가능
   .map(user => user.name);        // filter 후 map
 console.log(activeNames);         // ['철수', '민수']

 // forEach는 체이닝 불가
 // users.forEach(...).map(...);  // 오류! forEach는 undefined 반환

예제 14: filter - 조건에 맞는 요소만 추출

const nums = [1, 2, 3, 4, 5, 6];
// 짝수만 추출
const evens = nums.filter(num => num % 2 === 0); // 조건이 true인 것만
console.log(evens);               // [2, 4, 6]
// 객체 배열 필터링
const users = [
  { name: '철수', age: 20 },
   { name: '영희', age: 17 },
   { name: '민수', age: 25 }
 ];

 const adults = users.filter(user => user.age >= 20); // 성인만
 console.log(adults);              // [{ name: '철수', age: 20 }, { name: '민수', age: 25 }]

예제 15: find - 조건에 맞는 첫 번째 요소 찾기

const users = [
  { id: 1, name: '철수' },
  { id: 2, name: '영희' },
  { id: 3, name: '민수' }
];
// id가 2인 사용자 찾기
const user = users.find(user => user.id === 2); // 첫 번째 일치 항목
console.log(user);                // { id: 2, name: '영희' }

 // 없으면 undefined 반환
 const notFound = users.find(user => user.id === 99);
 console.log(notFound);            // undefined

예제 16: reduce - 배열을 하나의 값으로 축소

const nums = [1, 2, 3, 4, 5];
// 합계 구하기
const sum = nums.reduce((acc, cur) => acc + cur, 0);
// acc: 누적값(처음엔 0), cur: 현재값
console.log(sum);                 // 15
// 객체로 변환
const users = ['철수', '영희', '민수'];
 const obj = users.reduce((acc, name, idx) => {
   acc[idx] = name;                // 인덱스를 키로 사용
   return acc;                     // 누적값 반환 필수
 }, {});                           // 초기값은 빈 객체
 console.log(obj);                 // { 0: '철수', 1: '영희', 2: '민수' }

예제 17: 배열 메서드 체이닝

1. const nums = [1, 2, 3, 4, 5, 6];
2.
3. // 짝수만 필터링 → 2배 → 합계
4. const result = nums
5.   .filter(num => num % 2 === 0)   // [2, 4, 6]
6.   .map(num => num * 2)            // [4, 8, 12]
7.   .reduce((acc, cur) => acc + cur, 0); // 24
8.
9. console.log(result);              // 24

7. 삼항 연산자 (Ternary Operator, 터너리 오퍼레이터)

조건에 따라 값을 선택합니다. React의 조건부 렌더링에 자주 사용됩니다.

예제 18: 삼항 연산자 기본

  const age = 20;

  // 기존 방식 (if-else)
  let msg1;
  if (age >= 20) {
    msg1 = '성인';
  } else {
    msg1 = '미성년';
  }

   // 삼항 연산자
   const msg2 = age >= 20 ? '성인' : '미성년'; // 조건 ? 참일때 : 거짓일때
   console.log(msg2);                // '성인'

   // 중첩 사용 (비추천 - 복잡함)
   const score = 85;
   const grade = score >= 90 ? 'A' :
                 score >= 80 ? 'B' :
                 score >= 70 ? 'C' : 'D';
   console.log(grade);               // 'B'

8. 단축 평가 (Short-circuit Evaluation, 쇼트 서킷 이밸류에이션)

예제 19: && 연산자 - 조건부 렌더링

const isLogin = true;
const user = { name: '철수' };
// && : 왼쪽이 true면 오른쪽 실행
const msg1 = isLogin && '로그인됨'; // isLogin이 true이므로 '로그인됨' 반환
console.log(msg1);                // '로그인됨'
const msg2 = !isLogin && '로그인 필요'; // false이므로 false 반환
console.log(msg2);                // false

 // React에서 자주 사용
 const display = isLogin && `환영합니다, ${user.name}님`;
 console.log(display);             // '환영합니다, 철수님'

예제 20: || 연산자 - 기본값 설정

const name1 = '';                  // 빈 문자열 (falsy)
const name2 = null;                // null (falsy)
const name3 = '철수';              // 문자열 (truthy)
// || : 왼쪽이 falsy면 오른쪽 사용
const display1 = name1 || '게스트'; // ''는 falsy이므로 '게스트'
const display2 = name2 || '게스트'; // null은 falsy이므로 '게스트'
const display3 = name3 || '게스트'; // '철수'는 truthy이므로 '철수'
 console.log(display1);             // '게스트'
 console.log(display3);             // '철수'

예제 21: Nullish Coalescing (??) - null/undefined만 체크

const count1 = 0;                  // 0은 falsy지만 유효한 값
const count2 = null;               // null
// || 사용 (문제 있음)
const result1 = count1 || 10;      // 0은 falsy이므로 10 반환 (의도와 다름)
console.log(result1);              // 10 (잘못된 결과)
// ?? 사용 (올바름)
const result2 = count1 ?? 10;      // 0은 null/undefined가 아니므로 0 반환
 const result3 = count2 ?? 10;      // null이므로 10 반환

 console.log(result2);              // 0 (올바른 결과)
 console.log(result3);              // 10

예제 22: Optional Chaining (?.) - 안전한 속성 접근

const user1 = {
  name: '철수',
  addr: { city: '서울' }
};
const user2 = { name: '영희' };   // addr 속성 없음

// 기존 방식 (에러 발생 가능)
// console.log(user2.addr.city);  // 오류! Cannot read property 'city' of undefined

 // 안전한 방식
 console.log(user2.addr && user2.addr.city); // undefined (에러 없음)

 // Optional Chaining 사용
 console.log(user1.addr?.city);    // '서울'
 console.log(user2.addr?.city);    // undefined (에러 없음)

 // 메서드 호출에도 사용
 const obj = { getName: () => '철수' };
 console.log(obj.getName?.());     // '철수'
 console.log(obj.getAge?.());      // undefined (메서드 없어도 에러 없음)

9. Promise(프로미스)와 async/await

비동기(asynchronous, 어싱크러너스) 처리를 위한 문법입니다. API 호출에 필수입니다.

예제 23: Promise 기본

// Promise 생성
const promise = new Promise((resolve, reject) => {
  const success = true;

  setTimeout(() => {                // 2초 후 실행
    if (success) {
      resolve('성공!');            // 성공 시
    } else {
      reject('실패!');             // 실패 시
    }
  }, 2000);
 });

 // Promise 사용
 promise
   .then(result => {                // 성공 시 실행
     console.log(result);           // '성공!'
   })
   .catch(error => {                // 실패 시 실행
     console.log(error);
   });

예제 24: async/await - Promise를 쉽게

// API 호출 함수 (예시)
function fetchUser(id) {           // Promise를 반환하는 함수
  return new Promise(resolve => {
    setTimeout(() => {
      resolve({ id, name: '철수' });
    }, 1000);
  });
}

 // 기존 방식 (then 사용)
 fetchUser(1)
   .then(user => {
     console.log(user);
   });

 // async/await 사용
 async function getUser() {         // async 함수 선언
   const user = await fetchUser(1); // await로 Promise 기다림
   console.log(user);               // { id: 1, name: '철수' }
 }

 getUser();                         // 함수 호출

예제 25: async/await 에러 처리

 async function loadData() {
   try {                             // 에러 처리 시작
     const res = await fetch('https://api.example.com/data');
     const data = await res.json();  // JSON 변환 기다림
     console.log(data);
   } catch (error) {                 // 에러 발생 시
     console.log('에러:', error);
   }
 }

10. 모듈 (Module, 모듈) - import/export

파일 간 코드를 공유합니다. React 컴포넌트는 모두 모듈입니다.

예제 26: export - 내보내기

// utils.js
// named export (이름 지정 내보내기)
export const add = (a, b) => a + b;           // export 붙이기
export const subtract = (a, b) => a - b;

const multiply = (a, b) => a * b;
const divide = (a, b) => a / b;

export { multiply, divide };                  // 한 번에 내보내기

 // default export (기본 내보내기) - 파일당 하나만
 export default function greet(name) {         // default는 하나만 가능
   return `안녕 ${name}`;
 }

예제 27: import - 가져오기

// main.js
// named import (이름으로 가져오기)
import { add, subtract } from './utils.js';   // 중괄호 사용
console.log(add(5, 3));                       // 8

// 이름 변경하여 가져오기
import { multiply as mul } from './utils.js'; // as로 이름 변경
console.log(mul(4, 2));                       // 8

// 모두 가져오기
 import * as utils from './utils.js';          // * 사용
 console.log(utils.divide(10, 2));             // 5

 // default import (기본 가져오기)
 import greet from './utils.js';               // 중괄호 없이, 원하는 이름 사용 가능
 console.log(greet('철수'));                   // '안녕 철수'

 // named와 default 함께
 import greet, { add } from './utils.js';      // default를 먼저

11. 객체 단축 속성 (Property Shorthand, 프로퍼티 쇼트핸드)

예제 28: 객체 단축 문법

const name = '철수';
const age = 20;

// 기존 방식
const user1 = {
  name: name,                      // 속성명과 변수명이 같음
  age: age
};

 // 단축 속성
 const user2 = { name, age };       // 변수명과 같으면 생략 가능
 console.log(user2);                // { name: '철수', age: 20 }

 // 메서드 단축
 const obj1 = {
   sayHi: function() {              // 기존 방식
     console.log('안녕');
   }
 };

 const obj2 = {
   sayHi() {                        // function 키워드 생략
     console.log('안녕');
   }
 };

 // 계산된 속성명
 const key = 'name';
 const user3 = {
   [key]: '철수',                   // 변수를 속성명으로 사용
   [`${key}2`]: '영희'              // 표현식도 가능
 };
 console.log(user3);                // { name: '철수', name2: '영희' }

12. 자주 하는 실수와 해결법

실수 1: const 객체 수정

// 잘못된 생각
const obj = { a: 1 };
// obj = { b: 2 };               // 오류! const는 재할당 불가

// 올바른 방법
const obj = { a: 1 };
obj.a = 2;                        // 객체 속성 변경은 가능
obj.b = 3;                        // 새 속성 추가도 가능
console.log(obj);                 // { a: 2, b: 3 }

실수 2: 화살표 함수 객체 반환

// 잘못된 코드
const getUser = id => { id: id, name: '철수' }; // 중괄호를 코드 블록으로 인식
console.log(getUser(1));          // undefined

// 올바른 코드
const getUser = id => ({ id: id, name: '철수' }); // 소괄호로 감싸기
console.log(getUser(1));          // { id: 1, name: '철수' }

실수 3: map에서 return 누락

// 잘못된 코드
const nums = [1, 2, 3];
const doubled = nums.map(num => { num * 2 }); // 중괄호 사용 시 return 필요
console.log(doubled);             // [undefined, undefined, undefined]

// 올바른 코드 1
const doubled = nums.map(num => num * 2); // 중괄호 없으면 자동 return

// 올바른 코드 2
const doubled = nums.map(num => { return num * 2; }); // return 명시

실수 4: forEach로 배열 생성 시도

// 잘못된 코드
const nums = [1, 2, 3];
const doubled = nums.forEach(num => num * 2); // forEach는 undefined 반환
console.log(doubled);             // undefined

// 올바른 코드
const doubled = nums.map(num => num * 2); // map 사용
console.log(doubled);             // [2, 4, 6]

13. 연습 문제

문제 1: 배열 메서드 종합

다음 사용자 배열에서 20세 이상인 사용자의 이름만 추출하세요.

const users = [
  { name: '철수', age: 17 },
  { name: '영희', age: 22 },
  { name: '민수', age: 19 },
  { name: '지영', age: 25 }
];

// 답: ['영희', '지영']

문제 2: 구조 분해와 스프레드

user 객체에서 name을 추출하고, 나머지를 rest 변수에 담으세요.

const user = { name: '철수', age: 20, job: '개발자' };

// 답: const { name, ...rest } = user;

문제 3: async/await

다음 함수를 async/await으로 변환하세요.

function getData() {
  fetch('https://api.example.com/data')
    .then(res => res.json())
    .then(data => console.log(data));
}

문제 4: map vs forEach

다음 중 어떤 메서드를 사용해야 할까요?

const nums = [1, 2, 3, 4, 5];

// A. 각 숫자에 10을 더한 새 배열이 필요함
// B. 각 숫자를 콘솔에 출력만 하고 싶음

// 답: A는 map, B는 forEach

15. 핵심 요약

React에서 가장 많이 사용하는 문법 TOP 5

  1. map - 리스트 렌더링
  2. 구조 분해 할당 - Props 추출
  3. 화살표 함수 - 이벤트 핸들러
  4. 스프레드 연산자 - 불변성 유지
  5. 삼항 연산자 - 조건부 렌더링