문서 읽는 데 46분 · C1

C-1: JavaScript 입문

목차 40
전체 34강 중 13강 · HTML·CSS·JS
난이도 · 입문

안녕하세요, 홍순구 튜터입니다. 지난 시간까지 우리는 HTML로 뼈대를 세우고 CSS로 옷을 입혀서, 모든 화면에서 예쁘게 보이는 인스타그램을 완성했어요. 로그인 화면, 피드, 프로필까지 진짜 인스타그램과 거의 똑같이 생겼죠.

그런데 지난 시간 끝에 솔직하게 인정한 게 하나 있었어요. 우리 화면은 멈춰 있다는 거예요. 좋아요 버튼을 눌러도 숫자가 안 올라가고, 하트를 눌러도 아무 일이 없어요. 그냥 그림이죠. 사진을 인쇄해서 벽에 붙여둔 것과 다를 게 없어요.

오늘부터 그 멈춰 있던 화면에 생명을 불어넣습니다. 좋아요를 누르면 숫자가 실제로 올라가고, 조건에 따라 다른 메시지가 뜨고, 반복되는 일을 자동으로 처리하는 것. 이 "동작"을 담당하는 언어가 바로 JavaScript예요.

여기서 한 가지 구분을 해둘게요. CSS 애니메이션(하트가 통통 튀는 효과)도 곧 배우지만, 그건 "어떻게 보이느냐"의 문제예요. JavaScript는 "무엇을 하느냐"의 문제죠. 좋아요 숫자가 41에서 42로 진짜 바뀌는 것 — 그건 보이기의 문제가 아니라 동작의 문제고, JavaScript의 일이에요. 그래서 움직임(애니메이션)보다 논리(JavaScript)를 먼저 배웁니다.

텍스트
   HTML        CSS            JavaScript
   뼈대        옷·화장        움직임·논리
   ┌───────┐    ┌─────────┐       ┌───────────────┐
   │ 무엇이│    │ 어떻게  │       │ 무엇을 하는가 │
   │ 있는가│   │ 보이는가│      │ (좋아요 +1!)  │
   └───────┘    └─────────┘       └───────────────┘
   집의 구조    페인트·가구     전기·수도가 흐름

오늘은 JavaScript의 가장 기초인 변수(값을 담아두기), 자료형(값의 종류), 연산자(계산·비교·판정), 조건문(상황마다 다르게), 반복문(같은 일을 여러 번), 그리고 결과를 확인하는 콘솔을 배웁니다. 마지막엔 이걸 다 모아서 좋아요 카운터를 직접 만들어요.

💡 오늘 수업의 핵심 — "변수에 값을 담고, 연산자로 계산하고, 조건문·반복문으로 흐름을 제어해서, 멈춰 있던 화면에 '동작'을 만든다. 결과는 콘솔에 바로 찍어 확인한다." 🎯

🎯 학습 목표

  • <script> 태그로 HTML에 JavaScript를 연결하고, 개발자 도구 콘솔에서 결과를 확인합니다.
  • console.log()로 값을 출력하며 "코드를 치면 바로 결과가 보이는" 즉시성을 체감합니다.
  • 변수 let·const·var의 차이를 알고, 값을 담고 바꿉니다.
  • 자료형(숫자·문자열·불린·undefined·null)을 구분하고 typeof로 확인합니다.
  • 산술·비교·논리 연산자로 값을 계산하고 조건을 판정합니다.
  • 조건문 if/else/switch로 상황마다 다른 동작을 실행합니다.
  • 반복문 for/while/for...of로 같은 작업을 여러 번 수행합니다.
  • 변수·연산자·조건문·반복문을 모아 좋아요 카운터를 완성합니다.

Step 1: JavaScript 첫 만남 — console.log()로 결과 확인하기

JavaScript를 배우는 가장 빠른 길은, 코드를 한 줄 쓰고 결과가 바로 찍히는 걸 눈으로 보는 거예요. 이론은 그다음이에요. 먼저 손부터 움직여봅시다.

개발자 도구 콘솔 열기

브라우저에는 개발자를 위한 비밀 공간이 있어요. 바로 개발자 도구(DevTools)예요. 크롬에서 F12 키를 누르거나, 화면에 마우스 오른쪽 버튼 → "검사"를 누르면 열려요. 거기서 Console(콘솔) 탭을 클릭하세요.

콘솔은 JavaScript의 결과가 찍히는 칠판이라고 생각하면 돼요. 우리가 코드로 "이거 출력해줘"라고 시키면, 그 답이 여기에 나타나요.

HTML에 JavaScript 연결하기

CSS를 <link>로 연결했듯이, JavaScript는 <script> 태그로 연결해요. 우리 feed.html의 맨 아래, </body> 바로 앞에 이 한 줄이 들어가 있어요.

HTML
<!-- instagram-clone-frontend/feed.html -->
<script src="js/main.js"></script>

이렇게 연결해두면, feed.html을 열 때 브라우저가 js/main.js 파일에 적힌 JavaScript 코드를 위에서부터 차례대로 실행해요.

🙋 왜 <script></body> 바로 앞에 둘까?

🙋 학생 질문 — "튜터님, <script><head>에 넣으면 안 되나요?"

넣을 수는 있어요. 하지만 브라우저는 HTML을 위에서 아래로 읽어요. <script><head>(맨 위)에 두면, 아직 화면(HTML 본문)이 다 그려지기도 전에 JavaScript가 먼저 실행돼요.

지금은 콘솔에 글자만 찍으니 상관없지만, 나중에 화면의 버튼이나 사진을 JavaScript로 다룰 때는 "아직 그려지지도 않은 걸 만지려다" 문제가 생겨요. 그래서 화면이 다 그려진 뒤에 실행되도록 </body> 바로 앞에 두는 습관을 들이는 거예요.

첫 코드 — console.log()

이제 js/main.js를 열어봅시다. 맨 위에 이 두 줄이 있어요.

JavaScript
// instagram-clone-frontend/js/main.js
console.log("인스타 클론에 생명을 불어넣자!");
console.log("좋아요", 42, "개");

console.log(...)는 "괄호 안의 값을 콘솔에 출력해줘"라는 명령이에요. JavaScript에서 가장 많이 쓰는, 그리고 가장 친한 친구가 될 명령이죠. 큰따옴표로 감싼 글자(문자열)도, 숫자 42도 그대로 찍어줘요. 쉼표로 여러 개를 나란히 넘기면 한 줄에 띄어서 출력해요.

feed.html을 Live Server로 열고 콘솔을 보면 이렇게 찍혀요.

텍스트
인스타 클론에 생명을 불어넣자!
좋아요 42 개

코드를 저장하면 Live Server가 자동으로 새로고침하고, 콘솔에 결과가 바로 나타나요. 이 즉시성이 JavaScript 학습의 가장 큰 무기예요. 코드 한 줄 → 결과 한 줄. 글자를 바꿔서 저장하면 콘솔도 바로 바뀌어요. 직접 몇 번 바꿔보면서 손에 익혀보세요.

💡 콘솔에 직접 타이핑할 수도 있어요. 콘솔 탭의 빈 줄에 console.log("안녕")을 치고 엔터를 누르면 바로 실행돼요. 파일에 적기 전에 빠르게 실험할 때 좋아요.


Step 2: 변수 — let, const, var로 값을 담아두기

좋아요 숫자 42를 콘솔에 찍었죠. 그런데 이 숫자를 여러 번 쓰고, 나중에 바꾸기도 하려면 어딘가에 이름을 붙여서 담아둬야 해요. 그게 바로 변수(variable)예요.

변수는 값을 담는 상자예요. 상자에 이름표를 붙이고 값을 넣어두면, 그다음부터는 이름만 부르면 그 값이 튀어나와요.

텍스트
   let likeCount = 42

   likeCount  ┌──────┐
    (이름표)  │  42  │   담긴 값
              └──────┘

   likeCount = 43    같은 상자에 새 값으로 교체

   likeCount  ┌──────┐
              │  43  │
              └──────┘

세 가지 변수 선언 — let, const, var

JavaScript에서 변수를 만드는 방법은 세 가지예요. js/main.js의 Step 2 부분을 볼게요.

JavaScript
// instagram-clone-frontend/js/main.js
let likeCount = 42;     // let: 나중에 값을 바꿀 수 있는 변수
likeCount = 43;         // 재할당 OK
const username = "hong_tutor";  // const: 한 번 정하면 못 바꾸는 값
// username = "kim";    // const 재할당은 에러가 나요 (주석 풀면 확인)
var legacyVar = "옛날 방식";    // var: 예전 문법 (요즘은 거의 안 써요)
console.log(likeCount, username, legacyVar);

세 가지의 차이는 이래요.

키워드 값을 바꿀 수 있나? 언제 쓰나
const ❌ 못 바꿈 기본으로 쓰세요. 안 바뀌는 값
let ⭕ 바꿀 수 있음 값이 바뀌어야 할 때(카운터 등)
var ⭕ 바꿀 수 있음 옛날 문법. 새 코드엔 쓰지 마세요

const로 만든 username에 다른 값을 다시 넣으려고 하면 에러가 나요. 한 번 잠그면 못 바꾸는 상자거든요. 반대로 let으로 만든 likeCountlikeCount = 43처럼 새 값으로 바꿀 수 있어요.

어떤 걸 써야 할까?

규칙은 단순해요. 일단 const로 시작하세요. 그러다 "어, 이 값은 나중에 바뀌어야 하네" 싶으면 그때 let으로 바꾸면 돼요. 좋아요 숫자처럼 변하는 값만 let이고, 나머지(사용자 이름, 최대 글자 수 같은 고정값)는 const예요. var는 아주 오래된 코드에서나 보게 될 옛날 방식이니, 우리는 쓰지 않아요.

💡 혹시 Java를 배운다면, int number = 10;이 익숙하죠? JavaScript는 let number = 10;이에요. int, String 같은 타입을 안 써도 돼요. JavaScript가 값을 보고 알아서 판단하거든요.

콘솔 출력은 이래요.

텍스트
43 hong_tutor 옛날 방식

likeCount가 42에서 43으로 바뀐 게 보이죠?


Step 3: 자료형 — 값의 종류와 typeof

변수에 담는 값에는 종류가 있어요. 숫자 42와 글자 "hong_tutor"는 다른 종류죠. 이 종류를 자료형(data type)이라고 불러요. JavaScript의 기본 자료형 다섯 가지를 만나봅시다.

JavaScript
// instagram-clone-frontend/js/main.js
let count = 42;            // number  (숫자)
let name = "hong_tutor";  // string  (문자열)
let isPublic = true;      // boolean (참/거짓)
let caption;              // undefined (아직 값을 안 넣음)
let deletedAt = null;     // null    (의도적으로 비어 있음)

하나씩 볼게요.

  • number(숫자)42, 10.5처럼 숫자예요. 정수든 소수든 다 number 하나예요.
  • string(문자열)"hong_tutor"처럼 따옴표로 감싼 글자예요. 큰따옴표·작은따옴표 둘 다 돼요.
  • boolean(불린)true(참) 또는 false(거짓), 딱 두 값뿐이에요. "공개 게시물인가?", "로그인했나?" 같은 예/아니오를 담아요.
  • undefined — 변수를 만들었지만 아직 값을 안 넣은 상태예요. 빈 상자죠.
  • null — "의도적으로 비어 있음"이에요. undefined가 "깜빡하고 안 넣음"이라면, null은 "일부러 비워둠"이에요. 예를 들어 "삭제된 시각"이 아직 없으면 null로 표시해요.

typeof로 종류 확인하기

값의 종류가 궁금하면 typeof를 앞에 붙여요. 그러면 그 값의 자료형을 글자로 알려줘요.

JavaScript
// instagram-clone-frontend/js/main.js
console.log(typeof count);     // "number"
console.log(typeof name);      // "string"
console.log(typeof isPublic);  // "boolean"
console.log(typeof caption);   // "undefined"
console.log(typeof deletedAt); // "object" ← 유명한 함정! null인데 object로 나와요

콘솔 출력은 이래요.

텍스트
number
string
boolean
undefined
object

⚠️ typeof null"object"인 함정

마지막 줄을 보세요. deletedAt은 분명 null인데, typeof로 확인하면 "null"이 아니라 "object"가 나와요. 이건 JavaScript가 아주 옛날에 만들어질 때 생긴 유명한 버그예요. 너무 많은 코드가 이 동작에 의존하게 돼서, 고치고 싶어도 못 고치고 지금까지 남아 있어요. "아, null은 typeof가 object로 나오는구나" 하고 그냥 기억해두면 돼요. 여러분 잘못이 아니에요.

🙋 자료형이 왜 중요한가요?

🙋 학생 질문 — "튜터님, 종류를 왜 굳이 구분하나요?"

계산과 비교를 정확하게 하려고요. 숫자 42와 문자열 "42"는 사람 눈엔 같아 보이지만, 컴퓨터에겐 완전히 달라요.

숫자 42 + 143이지만, 문자열 "42" + 1은 글자를 이어붙여서 "421"이 돼요. 같은 +인데 종류에 따라 다르게 동작하죠. 그래서 "이 값이 숫자인가 글자인가"를 아는 게 중요해요. 다음 Step에서 이 차이를 직접 보게 될 거예요.


Step 4: 연산자 ① — 산술·비교

이제 값을 가지고 계산하고 비교해봅시다. 먼저 산술 연산자(더하기·빼기 등)와 비교 연산자(크다·같다 등)예요.

산술 연산자 — 계산하기

JavaScript
// instagram-clone-frontend/js/main.js
let likes = 42;
let newLikes = 8;
console.log(likes + newLikes); // 50  더하기
console.log(likes - 10);       // 32  빼기
console.log(likes * 2);        // 84  곱하기
console.log(likes / 4);        // 10.5 나누기
console.log(likes % 5);        // 2   나머지

+, -, *, /는 수학에서 본 그대로예요. 곱하기는 ×가 아니라 *, 나누기는 ÷가 아니라 /를 쓰는 것만 기억하세요.

마지막 %(나머지)가 조금 낯설 수 있어요. 42 % 5는 "42를 5로 나눈 나머지"라서 2예요. 나머지가 신기해 보여도 실무에서 자주 써요. 예를 들어 "짝수인지 홀수인지"는 숫자 % 2가 0이냐 아니냐로 알 수 있죠.

비교 연산자 — 비교하기

비교 연산자는 두 값을 비교해서 참(true) 또는 거짓(false)을 돌려줘요.

JavaScript
// instagram-clone-frontend/js/main.js
console.log(likes > 100);      // false
console.log(likes === 42);     // true   값과 타입이 모두 같은지
console.log(likes !== 50);     // true   다른지
console.log("42" === 42);      // false  문자열 "42" 와 숫자 42 는 다르다

>(크다), <(작다)는 익숙하죠. 중요한 건 같은지 비교하는 ===예요. 등호가 세 개인 게 포인트예요.

⚠️ ===는 등호 세 개

JavaScript에서 "같다"를 비교할 땐 등호를 세 개(===) 써요. 등호 하나(=)는 "값을 담는다"는 뜻이라 비교가 아니에요. ===는 "값도 같고 종류(자료형)도 같은가?"를 따져요.

그래서 마지막 줄 "42" === 42false예요. 둘 다 42처럼 보이지만, 하나는 문자열이고 하나는 숫자라서 종류가 다르거든요. Step 3에서 "자료형이 왜 중요하냐"고 했던 이유가 바로 여기예요. 항상 ===(등호 세 개)를 쓰는 습관을 들이면, 이런 종류 차이로 인한 실수를 막아줘요.

콘솔 출력은 이래요.

텍스트
50
32
84
10.5
2
false
true
true
false

Step 5: 연산자 ② — 논리

산술·비교에 이어, 이번엔 논리 연산자예요. 논리 연산자는 참·거짓을 조합해서 더 복잡한 조건을 만들어요. 예를 들어 "로그인했고 그리고 오늘 글을 안 썼으면 글쓰기를 권하자" 같은 거죠.

JavaScript
// instagram-clone-frontend/js/main.js
let isLoggedIn = true;
let hasPostedToday = false;
console.log(isLoggedIn && hasPostedToday); // false  AND: 둘 다 참이어야 참
console.log(isLoggedIn || hasPostedToday); // true   OR: 하나만 참이어도 참
console.log(!hasPostedToday);              // true   NOT: 반대로 뒤집기
let followers = 1200;
console.log(followers > 1000 && isLoggedIn); // true  팔로워 1000 초과 그리고 로그인 상태

세 가지를 정리하면 이래요.

  • && (AND, 그리고) — 양쪽이 둘 다 참이어야 참이에요. 하나라도 거짓이면 전체가 거짓이죠.
  • || (OR, 또는) — 둘 중 하나만 참이어도 참이에요. 둘 다 거짓일 때만 거짓이고요.
  • ! (NOT, 부정) — 참을 거짓으로, 거짓을 참으로 뒤집어요.
텍스트
   AND(&&)  둘 다 참  참        OR(||)  하나만 참  참
   true  && true  = true        true  || false = true
   true  && false = false       false || false = false
   false && false = false       true  || true  = true

   NOT(!)  뒤집기
   !true  = false
   !false = true

마지막 줄 followers > 1000 && isLoggedIn을 보세요. 먼저 followers > 1000(1200 > 1000)이 true이고, isLoggedIntrue라서, &&로 묶으면 둘 다 참이니 전체가 true예요. 이렇게 비교와 논리를 조합하면 "팔로워가 1000명을 넘고 로그인한 사용자에게만 보여주기" 같은 진짜 조건을 만들 수 있어요. 다음 Step에서 이 참·거짓을 조건문에 연결해요.

콘솔 출력은 이래요.

텍스트
false
true
true
true

Step 6: 조건문 — if, else, switch

지금까지 만든 참·거짓을 가지고, 이제 상황마다 다르게 행동하게 만들어봅시다. 그게 조건문이에요. "좋아요가 100을 넘으면 인기 게시물이라고 표시하고, 아니면 그냥 공감 메시지를 보여주자" 같은 거죠.

if / else if / else

JavaScript
// instagram-clone-frontend/js/main.js
let postLikes = 150;
if (postLikes > 100) {
  console.log("인기 게시물 🔥");
} else if (postLikes > 0) {
  console.log("공감을 받았어요");
} else {
  console.log("아직 좋아요가 없어요");
}

읽는 법은 위에서 아래로 흐르는 거예요.

텍스트
   postLikes (150)
        │
        
   > 100 ?  ── 예 ── "인기 게시물 🔥"   (여기서 끝)
        │ 아니오
        
   > 0 ?    ── 예 ── "공감을 받았어요"
        │ 아니오
        
   "아직 좋아요가 없어요"

if의 괄호 안 조건이 참이면 바로 아래 중괄호 { } 안의 코드를 실행하고, 나머지는 건너뛰어요. 거짓이면 다음 else if로 내려가서 또 따져보고요. 다 거짓이면 마지막 else가 실행돼요. postLikes가 150이니 첫 조건(> 100)이 참이라, "인기 게시물 🔥"이 찍히고 나머지는 건너뛰어요.

💡 오전에 Java로 if (likeCount > 0)를 배웠다면, JavaScript도 글자 하나 안 틀리고 똑같아요. 괄호·중괄호·else if까지 거의 같죠. 제어문은 언어가 달라도 거의 비슷하게 생겼어요.

switch — 값이 여러 갈래일 때

값 하나를 여러 경우와 비교할 땐 switch가 깔끔해요. 게시물이 사진인지 동영상인지 종류를 나눠 처리하는 예를 볼게요.

JavaScript
// instagram-clone-frontend/js/main.js
let mediaType = "image";
switch (mediaType) {
  case "image":
    console.log("사진 게시물");
    break;
  case "video":
    console.log("동영상 게시물");
    break;
  default:
    console.log("알 수 없는 형식");
}

switch는 괄호 안의 값(mediaType)을 각 case와 차례로 맞춰봐요. "image"와 일치하는 case를 찾으면 그 아래를 실행하고 break에서 멈춰요. 어디에도 안 맞으면 default가 실행되고요.

⚠️ break를 잊지 마세요

case 끝의 break는 "여기서 멈춰"라는 신호예요. 이걸 깜빡하면 일치한 case 아래 줄들이 줄줄이 다 실행되는 사고가 나요. switch를 쓸 땐 break를 꼭 챙기세요. mediaType"image"라서 콘솔엔 "사진 게시물"이 찍혀요.

텍스트
인기 게시물 🔥
사진 게시물

Step 7: 반복문 — for, while, for...of

같은 일을 여러 번 해야 할 때가 있어요. "좋아요 5번 누르기", "스토리 3장 자동 넘기기"처럼요. 이걸 복사·붙여넣기로 다섯 번 적는 대신, 반복문으로 한 번만 적고 여러 번 돌려요.

for — 정해진 횟수만큼

JavaScript
// instagram-clone-frontend/js/main.js
for (let i = 1; i <= 5; i++) {
  console.log(i + "번째 좋아요!");
}

for는 괄호 안에 세 가지를 적어요. 시작값, 계속할 조건, 매번 바뀌는 방식이에요.

텍스트
   for (let i = 1;  i <= 5;  i++)
        ────┬────  ──┬──   ─┬─
          시작값     조건    증가
          i=1       i<=5?    i를 1씩

   i=1  출력  i=2  출력  ...  i=5  출력  i=6 (조건 거짓) 

i는 1에서 시작해서, i <= 5가 참인 동안 반복하고, 한 바퀴 돌 때마다 i++로 1씩 늘어나요. i++i = i + 1의 짧은 표현이에요. i + "번째 좋아요!"는 숫자 i와 글자를 이어붙인 거예요(+로 문자열 연결). 출력은 이래요.

텍스트
1번째 좋아요!
2번째 좋아요!
3번째 좋아요!
4번째 좋아요!
5번째 좋아요!

💡 Java의 for (int i = 0; i < 5; i++)와 거의 똑같죠? intlet으로 바뀐 것 말고는 판박이예요.

while — 조건이 참인 동안

횟수가 딱 정해지지 않고 "조건이 만족되는 동안" 반복할 땐 while이 어울려요.

JavaScript
// instagram-clone-frontend/js/main.js
let remaining = 3;
while (remaining > 0) {
  console.log("스토리 자동 넘김까지 " + remaining);
  remaining = remaining - 1;
}

remaining이 3에서 시작해, remaining > 0이 참인 동안 반복해요. 한 바퀴마다 remaining = remaining - 1로 1씩 줄어들어서, 0이 되면 조건이 거짓이 되어 멈춰요.

⚠️ while은 멈출 조건을 꼭 만들어요

while 안에서 remaining을 줄이지 않으면, 조건이 영원히 참이라 반복이 멈추지 않아요(무한 루프). 화면이 멈춘 것처럼 보이죠. while을 쓸 땐 "이 값이 언젠가 조건을 거짓으로 만드는가?"를 꼭 확인하세요. 출력은 이래요.

텍스트
스토리 자동 넘김까지 3
스토리 자동 넘김까지 2
스토리 자동 넘김까지 1

for...of — 글자 하나씩 꺼내기

for...of는 여러 개가 모인 값에서 하나씩 꺼내 반복해요. 해시태그 글자를 한 글자씩 살펴볼게요.

JavaScript
// instagram-clone-frontend/js/main.js
let tag = "#daily";
for (const ch of tag) {
  console.log(ch);
}

tag라는 문자열에서 글자(ch)를 하나씩 꺼내서, #, d, a, i, l, y를 차례로 찍어요. for처럼 숫자를 직접 세지 않아도 알아서 처음부터 끝까지 돌아줘요. 출력은 이래요.

텍스트
#
d
a
i
l
y

Step 8: 좋아요 카운터 완성 — 배운 걸 한자리에

자, 이제 오늘 배운 변수·연산자·조건문·반복문·콘솔을 모두 모아서 진짜 좋아요 카운터를 만들어봅시다. 게시물 하나에 좋아요가 96개 있고, 5명이 차례로 좋아요를 누르면 어떻게 되는지를 시뮬레이션해요.

JavaScript
// instagram-clone-frontend/js/main.js
const POPULAR_THRESHOLD = 100;  // 이 숫자를 넘으면 "인기 게시물"
likeCount = 96;                 // 지금 좋아요 수로 다시 설정
console.log("시작 좋아요: " + likeCount);

// 5명이 차례로 좋아요를 누른다
for (let i = 1; i <= 5; i++) {
  likeCount = likeCount + 1;
  console.log(i + "번째 사용자가 좋아요! → 현재 " + likeCount);
}

// 인기 게시물인지 판정
if (likeCount >= POPULAR_THRESHOLD) {
  console.log("🔥 인기 게시물 달성! (" + likeCount + "개)");
} else {
  console.log("좋아요 " + likeCount + "개");
}

한 줄씩 뜯어볼게요.

  • const POPULAR_THRESHOLD = 100 — 인기 게시물 기준선이에요. 안 바뀌는 고정값이라 const로 잠갔어요.
  • likeCount = 96 — Step 2에서 만든 likeCount 상자를 다시 활용해요. 새로 let을 붙이지 않고 값만 96으로 바꿨어요(같은 상자 재사용).
  • for 반복문으로 5명이 한 명씩 좋아요를 눌러요. 누를 때마다 likeCount = likeCount + 1로 1씩 올라가고, 현재 숫자를 콘솔에 찍어요.
  • 마지막 if로 좋아요가 기준선(100) 이상인지 판정해요. >=는 "크거나 같다"예요.

콘솔 출력은 이래요.

텍스트
시작 좋아요: 96
1번째 사용자가 좋아요!  현재 97
2번째 사용자가 좋아요!  현재 98
3번째 사용자가 좋아요!  현재 99
4번째 사용자가 좋아요!  현재 100
5번째 사용자가 좋아요!  현재 101
🔥 인기 게시물 달성! (101개)

96에서 시작한 좋아요가 한 명씩 누를 때마다 올라가서, 100을 넘는 순간 "인기 게시물"로 판정되죠. 변수에 값을 담고(likeCount), 반복문으로 여러 번 돌리고(for), 연산자로 더하고(+ 1), 조건문으로 판정하는(if) — 오늘 배운 모든 게 이 작은 카운터 하나에 다 들어 있어요. 멈춰 있던 숫자가 드디어 움직이기 시작한 거예요.

🙋 모든 코드를 왜 한 파일(main.js)에 적었나요?

🙋 학생 질문 — "튜터님, 좋아요 카운터는 따로 파일을 나누는 게 깔끔하지 않나요?"

좋은 감각이에요. 실제로 코드가 많아지면 기능별로 파일을 나눠요. 그런데 지금 방식(일반 <script>)으로 파일을 여러 개 연결하면, 모든 파일이 같은 이름 공간을 공유해요. 그래서 두 파일에서 똑같이 let likeCount를 선언하면 "이미 있는 이름이야!" 하고 충돌이 나죠.

이 문제를 깔끔하게 푸는 게 모듈이라는 기능인데, 그건 조금 뒤(C-5)에 배워요. 모듈을 쓰면 파일마다 독립된 공간을 가져서 이름이 부딪히지 않거든요. 지금은 "한 파일에 모아 적는다"로 충분하니, 그렇게 진행해요.


마무리

오늘 우리는 멈춰 있던 화면에 첫 동작을 만들었어요. 짧게 되짚어볼게요.

  • 변수const(기본), let(바뀌는 값), var(옛날 방식). 값을 이름 붙여 담아둬요.
  • 자료형 — 숫자·문자열·불린·undefined·null. typeof로 종류를 확인하고요(단, typeof null"object" 함정).
  • 연산자 — 산술(+ - * / %), 비교(===, !==, >, <), 논리(&&, ||, !).
  • 조건문if/else if/else로 갈래를 나누고, switch로 여러 경우를 정리.
  • 반복문for(횟수), while(조건), for...of(하나씩 꺼내기).
  • 좋아요 카운터 — 이 전부를 모아 좋아요가 실제로 올라가는 동작을 완성.

JavaScript 문법이 생각보다 친근하죠? 특히 iffor는 오전에 Java로 배운 것과 거의 판박이예요. 언어가 달라도 "조건에 따라 갈라지고, 같은 일을 반복한다"는 프로그래밍의 뼈대는 똑같거든요.

다음 시간 예고

오늘 좋아요 카운터를 만들면서 살짝 답답한 게 있었어요. 만약 게시물이 여러 개라서 똑같은 카운터 코드를 게시물마다 복사해야 한다면? js/main.js가 끝없이 길어지겠죠. 같은 코드를 반복해서 쓰는 건 비효율이에요.

다음 시간엔 이 반복을 깔끔하게 묶는 함수(function)를 배웁니다. "좋아요 누르기"라는 동작에 이름을 붙여 한 번만 만들어두고, 필요할 때마다 그 이름을 불러 쓰는 거예요. 게다가 함수를 짧게 줄여 쓰는 화살표 함수(=>)라는 멋진 문법도 만나요. 오늘 길게 적은 코드가 다음 시간엔 훨씬 간결해질 거예요. 오늘 배운 변수와 조건·반복을 함수 안에 담아, 진짜 재사용 가능한 코드로 발전시켜봅시다!


과제

오늘 배운 JavaScript 기초를 직접 손에 익혀볼 차례예요. 기초 → 응용 → 탐구 순서로 풀어보세요. 모든 과제는 콘솔(console.log)에서 확인하고, 오늘 배운 변수·연산자·조건문·반복문만으로 충분히 풀 수 있어요. 함수나 화면 조작은 아직 안 써도 돼요.

[구현] 팔로워 수 등급 표시기 (기초)

js/main.js 맨 아래에 이어서, 팔로워 수에 따라 다른 등급을 콘솔에 찍는 코드를 만들어보세요.

  • let followerCount = 5400; 처럼 팔로워 수를 변수에 담으세요(숫자는 자유롭게).
  • if/else if/else로 다음처럼 판정해 출력하세요: 10000 이상이면 "인플루언서", 1000 이상이면 "인기 사용자", 그 미만이면 "새내기".
  • 변수의 숫자를 바꿔가며 세 등급이 모두 제대로 나오는지 콘솔에서 확인하세요.

[구현] 해시태그 글자 수 세기 (응용)

해시태그 문자열에서 글자가 몇 개인지를 반복문으로 직접 세어보세요. (글자 수를 한 번에 알려주는 기능은 일부러 쓰지 말고, 반복문으로 하나씩 세보는 게 목표예요.)

  • let tag = "#daily"; 처럼 해시태그를 변수에 담으세요.
  • let charCount = 0;으로 세는 변수를 0에서 시작하세요.
  • for...of로 글자를 하나씩 꺼내면서, 꺼낼 때마다 charCount를 1씩 늘리세요.
  • 반복이 끝난 뒤 console.log("글자 수: " + charCount);로 결과를 찍으세요. "#daily"는 6이 나와야 해요.

[탐구] =====의 차이 관찰하기

오늘은 항상 등호 세 개(===)를 쓰라고 했어요. 그런데 JavaScript엔 등호 두 개(==)도 있어요. 둘이 어떻게 다른지 콘솔에서 직접 비교해보고, 관찰한 걸 정리해보세요.

  • 콘솔에 console.log("42" === 42);console.log("42" == 42);를 각각 쳐보고 결과를 적으세요.
  • console.log(0 === false);console.log(0 == false);도 비교해보세요.
  • 두 결과가 왜 다른지, "종류(자료형)까지 따지는가 아닌가"라는 관점에서 한두 문장으로 설명해보세요. 그리고 왜 ===를 권하는지 자기 말로 정리해보세요.

생각해볼 주제

정답을 적는 문제가 아니에요. 오늘 배운 것의 "왜"를 곱씹어보는 질문들이에요. 스스로 답을 만들어본 뒤, 예시답안과 비교해보세요.

1. 왜 let보다 const를 기본으로 쓰라고 할까?

둘 다 변수를 만들 수 있고, let은 값까지 바꿀 수 있어서 더 자유로워 보여요. 그런데도 실무에선 "일단 const, 꼭 필요할 때만 let"을 권해요. 더 자유로운 let을 왜 아껴 쓸까요? 값이 바뀌지 않는다고 보장될 때의 안심, 그리고 코드를 읽는 사람이 얻는 정보라는 관점에서 생각해보세요.

2. 왜 결과를 화면이 아니라 콘솔에 먼저 찍어볼까?

오늘 우리는 좋아요 숫자를 화면에 띄우지 않고 콘솔에만 찍었어요. 진짜 인스타그램은 좋아요가 화면에 보이는데, 왜 우리는 굳이 콘솔부터 썼을까요? 화면에 그리는 것과 값이 맞는지 확인하는 것은 다른 일이라는 점, 그리고 문제가 생겼을 때 어디가 잘못됐는지 빨리 찾는다는 관점에서 생각해보세요.

3. typeof null"object"인 버그를 왜 안 고치고 두었을까?

명백한 버그인데도 JavaScript는 수십 년째 이걸 고치지 않고 있어요. 마음만 먹으면 고칠 수 있을 텐데도요. 왜 그냥 둘까요? 이미 그 동작에 기대어 돌아가는 수많은 웹사이트, 그리고 "고치는 게 오히려 더 많은 걸 망가뜨리는" 상황이라는 관점에서 생각해보세요. 이건 JavaScript만의 이야기가 아니라, 오래된 소프트웨어가 흔히 마주하는 고민이기도 해요.

✅ 예시 답안정답 보기

과제와 생각해볼 주제의 예시답안이에요. 정답이 하나만 있는 건 아니에요. 변수 이름이나 숫자는 취향대로 골라도 좋아요. 중요한 건 변수에 값을 담고, 조건문·반복문으로 흐름을 제어해서, 결과를 콘솔에 정확히 찍었는가 예요.


과제 예시답안

🎯 [과제 1 예시답안] 팔로워 수 등급 표시기

핵심 접근

팔로워 수를 변수에 담고, if/else if/else로 구간을 나눠 다른 등급을 찍는 과제예요. 오늘 Step 6에서 좋아요를 "인기/공감/없음"으로 나눈 것과 똑같은 패턴이에요. 핵심은 큰 기준부터 차례로 따지는 거예요. 10000을 먼저 보고, 그다음 1000, 마지막에 나머지 순서로요.

예시 구현

JavaScript
// instagram-clone-frontend/js/main.js 맨 아래에 이어서

let followerCount = 5400;

if (followerCount >= 10000) {
  console.log("인플루언서");
} else if (followerCount >= 1000) {
  console.log("인기 사용자");
} else {
  console.log("새내기");
}

followerCount가 5400이면, 첫 조건(>= 10000)은 거짓이라 건너뛰고, 둘째 조건(>= 1000)이 참이라 "인기 사용자"가 찍혀요. 숫자를 12000으로 바꾸면 "인플루언서", 300으로 바꾸면 "새내기"가 나와요.

텍스트
인기 사용자

채점 포인트

항목 확인 내용
변수 사용 팔로워 수를 변수(let)에 담았는가
큰 값부터 >= 10000>= 1000 → 나머지 순서로 따졌는가
else 처리 마지막은 else로 받아 빠짐없이 처리했는가
확인 숫자를 바꿔가며 세 등급이 모두 나오는지 확인했는가

흔한 실수

  • 작은 값부터 따짐>= 1000을 먼저 쓰면, 12000도 1000 이상이라 "인기 사용자"에서 멈춰버려요. else if는 위에서부터 참인 걸 찾으면 멈추니, 큰 기준을 먼저 둬야 해요.
  • else if 없이 if만 나열 — 조건을 다 if로만 적으면, 여러 조건이 동시에 참일 때 메시지가 두 번 찍혀요. 갈래가 하나만 골라지길 원하면 else if로 이어야 해요.

🎯 [과제 2 예시답안] 해시태그 글자 수 세기

핵심 접근

문자열의 글자를 반복문으로 하나씩 꺼내면서, 꺼낼 때마다 세는 변수를 1씩 늘리는 과제예요. 글자 수를 한 번에 알려주는 기능을 안 쓰고 직접 세보는 게 목표라, 반복문의 동작을 손으로 느끼게 돼요. 핵심은 세는 변수를 0에서 시작해서, for...of가 한 바퀴 돌 때마다 1씩 더하는 거예요.

예시 구현

JavaScript
// instagram-clone-frontend/js/main.js 맨 아래에 이어서

let tag = "#daily";
let charCount = 0;

for (const ch of tag) {
  charCount = charCount + 1;
}

console.log("글자 수: " + charCount);

charCount를 0에서 시작하고, for...of"#daily"의 글자(#, d, a, i, l, y)를 하나씩 꺼낼 때마다 charCount를 1씩 늘려요. 글자가 6개니 반복이 6번 돌고, 결과는 6이에요.

텍스트
글자 수: 6

채점 포인트

항목 확인 내용
세는 변수 시작 charCount를 0에서 시작했는가
반복마다 증가 for...of 안에서 한 글자당 1씩 늘렸는가
결과 위치 합계를 반복문이 끝난 뒤에 찍었는가
확인 "#daily"에서 6이 나오는지 확인했는가

흔한 실수

  • charCount를 반복문 안에서 0으로 초기화 — 0으로 만드는 줄을 for 안에 넣으면, 매번 0으로 되돌아가서 결과가 늘 1이 돼요. 시작값은 반복문 바깥에서 한 번만 정해야 해요.
  • 합계를 반복문 안에서 찍음console.logfor 안에 두면 1, 2, 3… 처럼 중간 과정이 다 찍혀요. 최종 글자 수만 보고 싶으면 반복이 끝난 뒤에 찍어야 해요.

🎯 [과제 3 예시답안] =====의 차이 관찰하기

핵심 접근

등호 세 개(===)와 두 개(==)가 어떻게 다른지 콘솔로 직접 확인하는 과제예요. 한 문장으로 요약하면, ===는 종류(자료형)까지 따지고, ==는 종류가 다르면 슬쩍 맞춰서 비교해요. 그래서 결과가 갈려요.

예시 관찰 결과

JavaScript
console.log("42" === 42);  // false  — 문자열 vs 숫자, 종류가 다름
console.log("42" == 42);   // true   — ==는 종류를 맞춰서 비교(둘 다 42로)
console.log(0 === false);  // false  — 숫자 vs 불린, 종류가 다름
console.log(0 == false);   // true   — ==는 0과 false를 같게 봄

===를 쓴 줄은 둘 다 false예요. "42"(문자열)와 42(숫자)는 종류가 다르고, 0(숫자)과 false(불린)도 종류가 다르니까요. 반면 ==를 쓴 줄은 둘 다 true예요. ==는 종류가 다르면 한쪽을 슬쩍 바꿔서(문자열 "42"를 숫자 42로, false를 0으로) 비교하거든요.

===를 권하나

==의 "슬쩍 맞춰주는" 동작은 편해 보이지만, 예상 못 한 결과를 낳아요. 0 == falsetrue라는 건 직관과 어긋나죠. 이런 깜짝 동작은 찾기 어려운 버그가 돼요. 그래서 항상 ===를 써서 "값도 종류도 똑같을 때만 같다"로 명확하게 비교하는 걸 권해요.

채점 포인트

항목 확인 내용
결과 관찰 네 줄의 true/false를 정확히 적었는가
차이 설명 "종류까지 따지는가 아닌가"로 차이를 설명했는가
결론 ===를 권하는 이유를 자기 말로 정리했는가

흔한 실수

  • ==가 항상 틀렸다고 단정==가 나쁜 게 아니라, 종류를 맞춰주는 동작이 예측을 어렵게 한다는 거예요. "틀림"이 아니라 "예상 밖 결과를 만든다"로 이해하는 게 정확해요.

생각해볼 주제 예시답안

1. 왜 let보다 const를 기본으로 쓰라고 할까?

let이 더 자유로운데도 const를 기본으로 권하는 건, "안 바뀐다"는 보장 자체가 가치이기 때문이에요.

첫째, 실수를 막아줘요. const로 잠근 값에 실수로 다른 값을 넣으려 하면 바로 에러가 나서, 잘못을 즉시 알아챌 수 있어요. let이면 조용히 바뀌어 버려서 나중에 원인을 찾기 어렵죠.

둘째, 코드를 읽는 사람에게 정보를 줘요. const라고 적힌 걸 보면 "아, 이 값은 끝까지 안 바뀌는구나" 하고 안심하고 읽을 수 있어요. 반대로 let이면 "이건 어딘가에서 바뀔 수 있겠네" 하고 계속 신경 써야 해요. 그래서 진짜 바뀌는 값만 let으로 두면, let이 곧 "여기 주의" 신호가 되는 거예요.

🎯 면접관을 홀리는 핵심 멘트

"저는 const를 기본으로 쓰고, 재할당이 꼭 필요한 변수에만 let을 써요. const는 단순한 문법이 아니라 '이 값은 안 바뀐다'는 의도를 코드로 적어두는 거라서, 읽는 사람과 미래의 저에게 주는 안전장치라고 생각합니다."

2. 왜 결과를 화면이 아니라 콘솔에 먼저 찍어볼까?

"값이 맞는지 확인하는 일"과 "화면에 예쁘게 그리는 일"은 서로 다른 작업이기 때문이에요.

콘솔은 값이 맞는지 확인하는 가장 빠른 도구예요. 좋아요 숫자가 96에서 101로 제대로 올라가는지를, 화면 디자인을 손대지 않고도 즉시 확인할 수 있죠. 만약 화면에 그리는 것부터 시작하면, 숫자가 틀렸을 때 "계산이 틀린 건지, 화면에 잘못 그린 건지" 구분이 안 돼요.

그래서 순서를 나누는 거예요. 먼저 콘솔로 "값(논리)이 맞다"를 확인하고, 그게 확실해진 다음에 화면에 그리기로 넘어가요. 그러면 문제가 생겨도 어느 단계가 잘못됐는지 빨리 좁힐 수 있어요. 화면 조작은 다음 카테고리에서 본격적으로 배워요.

🎯 면접관을 홀리는 핵심 멘트

"저는 로직과 화면 표시를 분리해서 확인해요. 먼저 콘솔로 값이 맞는지 검증하고, 그게 확실해진 뒤에 화면에 반영하죠. 그래야 버그가 났을 때 '계산이 틀렸나, 그리기가 틀렸나'를 한 번에 좁힐 수 있거든요."

3. typeof null"object"인 버그를 왜 안 고치고 두었을까?

고치는 것이 오히려 더 큰 피해를 부르기 때문이에요. 이건 "하위 호환성(backward compatibility)"이라는, 오래된 소프트웨어의 핵심 고민이에요.

JavaScript는 전 세계 수십억 개의 웹 페이지에서 돌아가요. 그중 어떤 코드는 typeof null"object"라는 그 동작에 기대어 만들어졌을 수 있어요. 만약 이걸 "null"로 "고치면", 그 동작에 의존하던 사이트들이 한순간에 망가질 수 있죠. 버그 하나를 바로잡으려다 멀쩡히 돌아가던 수많은 사이트를 깨뜨리는 거예요.

그래서 "명백한 버그지만, 고치는 비용이 두는 비용보다 크다"는 판단으로 그대로 둔 거예요. 이건 JavaScript만의 이야기가 아니에요. 오래 살아남은 소프트웨어일수록 "이미 의존하는 사람들"이 많아서, 과거의 결정을 함부로 바꾸지 못하는 무게를 지게 돼요.

🎯 면접관을 홀리는 핵심 멘트

"typeof nullobject인 건 유명한 버그지만, 저는 이걸 하위 호환성의 대표 사례로 봐요. 이미 그 동작에 의존하는 코드가 너무 많아서, 고치는 순간 멀쩡한 사이트들이 깨지거든요. 오래된 플랫폼은 '버그를 고치는 비용'과 '깨뜨리는 비용'을 저울질해야 한다는 걸 보여주는 예라고 생각합니다."

전체 목록 HTML·CSS·JS