8 분 소요

자바스크립트(JS)

자바스크립트(JavaScript)는 웹에서 동적인 동작을 구현하기 위한 대표적인 프로그래밍 언어입니다. HTML과 CSS로 만들어진 웹페이지에 생명력을 불어넣는 역할을 하죠.

이 글은 JS의 기초를 정리하면서 개념을 다지고, 프론트엔드 개발 관점에서 자주 쓰이는 문법을 정리하기 위한 목적입니다.

🔤변수 선언

변수(Variable)는 값을 저장해두는 이름 붙은 저장소입니다. 필요할 때 꺼내 쓰거나 바꿀 수 있어요.

let 이름 = '홍길동'; 
const 나이 = 30;
var 직업 = '개발자';
  • let: 변경 가능한 변수 선언 (블록 스코프)
  • const: 변경 불가능한 상수 선언 (블록 스코프)
  • var: 예전 방식으로 함수 스코프를 가짐. 호이스팅 문제로 지양됨

📌 프론트엔드 관점:

  • 컴포넌트 상태나 DOM 제어 변수 → let
  • 설정값, 불변 데이터 → const
  • var는 사용하지 않는 것이 좋음

🧬 데이터 타입

데이터 타입(Data Type)은 값이 어떤 종류인지 나타내는 분류입니다.

▶️ 기본형 (Primitive Type)

  • string: 문자열
  • number: 숫자
  • boolean: 참/거짓
  • null: 명시적으로 “없음”
  • undefined: 값이 할당되지 않음

▶️ 참조형 (Reference Type)

  • object: 객체 (여러 속성을 가짐)
  • array: 배열 (값들의 순서 있는 집합)
  • function: 함수 (실행 가능한 코드 블록)
const 이름 = "임시언"; // string
const 나이 = 28; // number
const 개발자 = true; // boolean
const 취미 = {"코딩", "산책"}; // array
const 정보 = {이름 : "시언", 나이: 28}; //object

그렇다면 이 타입을 왜 나눠놨을까?

➡️ 다양한 종류의 데이터를 효율적이고 정확하게 처리하기 위해서

📌 프론트엔드 관점:

  • API 응답 → 객체 또는 배열 형태가 많음
  • 타입을 정확히 이해해야 렌더링 오류 방지 가능
  • TypeScript와 연계 시 강력한 타입 체크 가능

👑 조건문

조건문은 특정 조건에 따라 실행할 코드를 분기합니다. 참/거짓에 따라 실행 코드를 다르게 만들 수 있어서 자주 사용합니다.

const 나이 = 29;

if (나이 >= 20) {
    console.log("성인")
}else {
    console.log("미성년자")
}

📌 프론트엔드 관점:

  • 로그인 여부, 권한, 상태값에 따라 UI를 다르게 구성할 때 자주 사용됩니다.

✅ 삼항 연상자

삼항 연산자는 리액트에서 어떤 컴포넌트를 생성했을 때, props로 설정해둔 값을 받아 다른 결과를 보일 때 제일 자주 사용했던 기억이 납니다.

그렇다면 삼항 연산자란 무엇일까요?

삼항연산자(termary operator)는 세 개의 피연산자를 사용하는 조건 연산자로, 조건에 따라 값을 선택할 때 짧고 간결하게 조건문을 표현할 수 있는 문법입니다.

// 기본형
조건 ? 참일   : 거짓일  
const 상태 = (나이 >= 20) ? "성인" : "미성년자";
console.log(상태);

>>> 성인

삼항 연산자는 간단한 조건 분기에는 유용하지만, 복잡한 조건에서 중첩되면 가독성이 떨어집니다.

사용을 지양합니다!

📌 프론트엔드 관점:

  • 컴포넌트 조건부 렌더링 ({조건 ? A : B})
  • 버튼 상태, 색상 등 UI 조건 분기에 자주 쓰임

🔍헷깔릴 수 있는 문법 : 널 병합 연산자

오늘 TestScript를 작성하면서 헷깔려 잘못 설명한 개념이 있어서 이 기회에 다시 정의하려고 합니다.

바로 ??를 사용하는 널 병합 연산자(Null Coalescing Operator)입니다.

JavaScript에서 ?? 기호로 쓰이며, null, 또는 undefined인 경우에만 대체값을 제공하는 연산자 입니다.

➡️ 피연산자가 null 또는 undefined일 경우에만 오른쪽 값을 반환

값1 ?? 값2

값1이 null 또는 undefined라면 값2를 반환합니다.

값1이 그외의 값(0, false, ""…)이라면 값1을 반환합니다.

//예시
let name;
let hiName = name ?? "이름없음";
console.log(hiName); 

>>> 이름없음

nameundefined니까 이름없음이 출력됩니다.

✅ 사용자 입력에서 0, false, "" 같은 것을 유효한 값으로 인정해야할때 사용합니다. 오직 nullundefined를 찾아 관리하기 위한 용도로 용이합니다.

||와 차이점은?

||는 falsy한 값을 전부 판단합니다.

const nickname = "" || "익명"
console.log(nickname)
>>> 익명

const nickname = "" ?? "익명"
console.log(nickname)
>> ""

""||에선 falsy이기 때문에 "익명"으로 넘어가지만,

??에서는 null 또는 undefined가 아니므로 "" 그대로 사용됩니다.

  • falsy한 값의 예

    false, 0, "", null, undefined, NaN

🔁반복문

같은 코드를 여러 번 실행하고 싶을 때 사용합니다.

👉 for문

for (let i = 0; i < 3; i++) {
  console.log(i); // 0, 1, 2 출력
}

i라는 초기값을 설정하고 중간에는 범위 그리고 마지막에는 어떻게(?) 저 범위까지 갈 것인지를 설정하여 for문을 사용합니다.

👉 while문

let i = 0;
while (i < 3) {
  console.log(i);
  i++;
}

**👉 forEach(배열 반목문)**

const 색상 = ["빨강", "파랑", "노랑"];
색상.forEach(() => {
  console.log(`색상: ${}`);
});

널 병합 연산자 (??)

값1 ?? 값2
  • 값1null 또는 undefined일 때만 값2 반환
  • 0, false, ""는 유효한 값으로 인정
let name;
let displayName = name ?? "이름 없음";  // "이름 없음"

📌 프론트엔드 관점:

  • 사용자 입력값이 비어있을 때 기본값 설정
  • 옵션값에만 fallback 값을 줄 때 유용

🔄 || 와 비교

  • ||는 falsy한 값 전부 판단 (0, false, "", null, undefined, NaN 등)
"" || "기본" // "기본"
"" ?? "기본" // ""

🔁 반복문

같은 동작을 여러 번 반복할 때 사용하는 문법입니다.

▶️ for문

for (let i = 0; i < 3; i++) {
  console.log(i); // 0, 1, 2
}

▶️ while문

let i = 0;
while (i < 3) {
  console.log(i);
  i++;
}

▶️ forEach (배열 반복)

const 색상 = ["빨강", "파랑", "노랑"];
색상.forEach((색) => {
  console.log(`색상: ${색}`);
});

📌 프론트엔드 관점:

  • 리스트 렌더링 (.map()과 함께)
  • 배열 기반 데이터 순회 처리에 필수

🔧 함수 선언과 호출

함수(Function)는 반복적으로 사용되는 로직을 하나로 묶어두는 코드 덩어리입니다.

function 인사(이름) {
  return `안녕하세요, ${이름}님!`;
}

console.log(인사("시언")); // 안녕하세요, 시언님!

📌 프론트엔드 관점:

  • 이벤트 핸들러, API 호출, 상태 변경 처리 등에서 자주 사용

📦 배열과 객체 다루기

배열과 객체는 둘 다 값을 여러 개 저장할 수 있는 자료구조입니다. 그러나 이 둘의 차이점은 아래 표를 보고 알 수 있습니다.

✅ 핵심 차이점 요약

구분 배열 (Array) 객체 (Object)
구조 순서 있는 값들의 집합 키-값 쌍의 집합
접근 방식 인덱스(숫자) 기반 키(문자열 또는 심볼) 기반
사용 목적 목록, 리스트 형태의 데이터 속성, 설정값 등 구조화된 데이터
대표 사용 예시 댓글 목록, 상품 리스트 사용자 정보, 설정값, API 응답

자바스크립트에서 배열도 객체의 일종입니다. 하지만 내장 함수와 자료 구조 목적이 다르기 때문에 구분해서 사용합니다.

상황 배열 사용 객체 사용
댓글, 상품, 유저 리스트
한 명 유저의 정보 (이름, 나이, 이메일)
JSON API 응답 처리 둘 다 혼합됨 → 보통 배열 안에 객체들  

실무에서 배열 안에 객체 구조를 자주 사용하는데, 어쩔때 쓰는 걸까??

➡️ 동일한 구조를 가진 여러 데이터를 표현할 때 사용하는 방식

const user = [
    {id : 1, name : "길동", age: 29},
    { id: 2, name: "지민", age: 31 },
  	{ id: 3, name: "윤서", age: 27 },
];

console.log(user[0].name);
>>> 길동

여기서 user는 사용자 정보를 담은 객체들이 들어있는 배열이고 각각의 객체는 한 사람에 대한 정보입니다.

❓왜 이렇게 사용하는 것 일까?

배열 형태이니 순서대로 반복이 가능하며 객체니까 각 항목에 이름(key)를 붙여 의미있는 데이터를 담을 수 있습니다.

▶️ 배열 접근

const 색상 = ["빨강", "초록", "파랑"];
console.log(색상[1]); // "초록"

▶️ 객체 접근

const 사람 = { 이름: "시언", 나이: 29 };
console.log(사람.이름); // "시언"

📌 프론트엔드 관점:

  • 리스트 렌더링, API 응답 처리, 컴포넌트 Props 관리 등 핵심 요소

    1. 리스트 렌더링

      {users.map(user => (
      <div key={user.id}>
          <p>{user.name}</p>
          <p>{user.age}</p>
      </div>
      ))}
      
    2. API 응답 처리

      {
          "status": "success",
              "data":[
                  {"id": 1, "title": "제목", "author": "홍길동"},
                  {"id": 2, "title": "제목", "author": "박길동"},
                  {"id": 3, "title": "제목", "author": "최길동"},
              ]
      }
      

🎯 이벤트 처리 (DOM)

이벤트(Event)는 유저의 행동에 반응하여 발생하는 동작입니다.

const 버튼 = document.querySelector("button");
버튼.addEventListener("click", () => {
  alert("버튼 클릭됨!");
});

📌 프론트엔드 관점:

  • 사용자 입력 처리 (클릭, 키 입력 등) → 리액트에선 onClick, onChange 등으로 사용

⏱️ 비동기 처리 (Promise / async-await)

JS는 기본적으로 동기적으로 동작하지만, 네트워크 요청처럼 시간이 걸리는 작업은 비동기로 처리합니다.

▶️ Promise 예시

fetch("https://api.example.com")
  .then(res => res.json())
  .then(data => console.log(data));

▶️ async-await 예시

async function getData() {
  const res = await fetch("https://api.example.com");
  const data = await res.json();
  console.log(data);
}

📌 프론트엔드 관점:

  • API 통신, 사용자 인증, 로딩 처리 등에 필수

👑 배열 고차함수 (Array Higher0Order Functions)

배열을 가공하거나 변형할 때 자주 사용되는 함수 입니다.

JS에서 배열의 각 요소를 순회하거나, 조건에 맞게 걸러내고, 새로운 배열을 만들 때 유용합니다.

✅ 고차함수란?

함수를 인자로 받거나, 함수를 반환하는 함수를 말합니다.

➡️ 배열 고차함수는 배열에 대해 어떤 동작(함수)을 반복 적용하는 것입니다.

🔑 자주 쓰는 배열 고차함수

함수 설명 반환값
forEach() 반복만 함 없음 (undefined)
map() 배열 변형 새로운 배열
filter() 조건에 맞는 요소만 추출 새로운 배열
find() 조건을 만족하는 첫 번째 요소 반환 요소 1개 or undefined
some() 하나라도 조건을 만족하면 true Boolean
every() 모두가 조건을 만족해야 true Boolean
reduce() 누적 계산 (합계, 평균 등) 어떤 값이든 가능

▶️ forEach() - 단순 반복

const 색상 = ["빨강", "파랑", "노랑"];
색상.forEach((, i) => {
    console.log(`${i}번 색상은 ${}`)
})

단순 출력이나 DOM 조작 등에 사용합니다.

📌 반환값이 없음

▶️ map() - 배열 변형

const 숫자 = [1, 2, 3];
const 제곱 = 숫자.map(n => n * n);
console.log(제곱); // [1, 4, 9]

📌 새로운 배열 반환

리스트 렌더링 시에 많이 사용합니다.

▶️ filter() - 조건에 맞는 요소만 추출

const 숫자 = [1, 2, 3, 4, 5];
const 짝수 = 숫자.filter(n => n % 2 === 0);
console.log(짝수); // [2, 4]

조건을 만족하는 모든 요소를 뽑아낸 배열입니다.

📌 프론트엔드 관점:

  • 리스트 렌더링, 조건 필터링, 데이터 가공 시 필수 활용

▶️ find() - 조건에 맞는 첫 요소

const 사람들 = [
    {id: 1, name: "길동"},
    {id: 2, name: "흥부"}
];
const 찾은사람 = 사람들.find(p => p.id === 2);
console.log(찾은사람); // {id : 2, name: "흥부"}

▶️ some() / every()

const 나이들 = [19, 20, 23];
console.log(나이들.some(age => age < 20)); //true
console.log(나이들.every(age => age >= 18)); // true
  • some: 하나라도 true면 true
  • every: 모두가 true여야 true

▶️ reduce() - 누적 계산

const 점수 = [80, 90, 100];
const 합계 = 점수.reduce((acc, cur) => acc + cur, 0);
console.log(합계); //270

📌acc: 누적값, cur: 현재값

합계, 곱, 평균, 객체 그룹화 등에 사용

  • .map() → 리스트 렌더링
  • .filter() → 검색/조건 필터
  • .reduce() → 장바구니 총합 계산
  • .find() → 특정 요소 찾기 (예: 유저 ID)
  • .some() → 체크박스 중 하나라도 선택됐는지 확인

🧩 구조 분해 할당 / 객체 단축 표기법

▶️ 구조 분해 할당 (Destructuring Assignment)

객체나 배열에서 원하는 값을 꺼내는 문법입니다.

코드의 간결성과 가독성 향상에 유리합니다.

const 사람 = { 이름: "시언", 나이: 29 };
const { 이름, 나이 } = 사람;
console.log(이름); // "시언"
  • 사람.이름, 사람.나이를 따로 접근하지 않아도 변수로 바로 꺼냅니다.

  • 변수명은 객체 키 이름과 일치해야합니다.

    function Profile({name, age}) {
        return <div>{name} - {age}</div>;
    }
    

▶️ 배열 구조 분해

const 색상 = ["빨강", "노랑"];
const [첫번째, 두번째] = 색상;
  • 순서 기준으로 값을 꺼냅니다.

  • 객체처럼 이름 기반이 아니라 인덱스 기준입니다.

    const [, onlySecond] = ["a", "b", "c"];
    console.log(onlySecond);
      
    >> "b"
    

중첩 구조 분해 할당

const user = {
    name: "",
    address: {city: "서울", zip: "12345"}
};

const {
    address: {city}
} = user;

console.log(city);

>> "서울"

##### 객체 구조 이해

user객체

{
    name: "",
    address:{
      city: "서울", 
      zip:"12345"
    }
}

그래서 user.address.city서울에 접근할 수 있다.

user객체에서 city값만 꺼내고 싶을때 구조 분해를 사용하면 더 간결하게 쓸 수 있습니다.

구조분해 문법
const {
    address: {city}
} = user;

user라는 객체 안에 address라는 키가 있고, 그 값도 객체입니다.

address 객체 안에 있는 city 값을 꺼내서 변수 city로 선언하는 겁니다.

📌 주소를 꺼내는 것이 아니라 주소 안의 city만 꺼내서 const city가 되는 것입니다.

중첩된 구조가 정확히 존재해야해서 user.address.city가 없으면 에러가 발생할 수 있습니다.

선택적 체이닝을 같이 쓰면 더 안전!

const city = user?.address?.city;

▶️ 객체 단축 표기법

변수명을 키로 사용할 때 키와 값이 같으면 생략가능합니다.

const 이름 = "시언";
const 나이 = 29;
const 사람 = { 이름, 나이 }; // { 이름: "시언", 나이: 29 }

{이름: 이름, 나이: 나이}를 줄여쓴 상태로 import하고 객체를 구성할 때 특히 유용합니다.

📌 프론트엔드 관점:

  • 컴포넌트 Props 처리, API 데이터 가공 시 매우 자주 사용됨

카테고리:

업데이트:

댓글남기기