자바스크립트 기초 문법 프로젝트

J·2025년 5월 12일

일단 단어 외우고 문법을 외운 다음 언어를 배우는 방법은 어릴 적 영어를 배울 때 해봤으나 별로 효과적이진 않았다. 자바스크립트를 배울 땐 다른 방법을 써보자. 작은 프로젝트를 구현하며 필요한 문법을 그때 그때 익혀보자.

들어가기 전에: Node.js 환경 설정

자바스크립트는 웹브로우저에서 작동되게 설계된 언어이다. 이를 웹브라우저 밖에서 동작시키기 위해선 별도의 환경 구축이 필요하다. 관련된 내용이 필요한 사람은 아래 링크를 참고하자.
훌륭한 블로그 링크

만들고 싶은 것

필자는 아무것도 모를 땐 숫자 비교 게임을 만든다. 이 아이디어는 Swift 강사로 유튜브에서 활동하고 있는 Chris Cheng의 영상에서 빌려왔다.
Starting The War Card Game App - Lesson 4 (2024 / SwiftUI)

목표

  1. 컴퓨터와 사용자 둘에게 숫자를 할당한다.
  2. 둘 중 큰 쪽이 승리한다.

계획

우리는 탱크를 만들고 싶다. 여러 기능을 가진 멋진 프로그램을 만들고 싶다. 그러나 많은 교육자료들은 이 탱크를 위에서부터 아래로 순서대로 가르친다. 탱크를 만들고 싶어도 일단 굴러가는 킥보드부터 만들자. 그리고 자전거, 오토바이, 자동차처럼 탱크처럼 굴러가는 것들을 보다 탱크스럽게 만들자. 그리고 마지막에 우리가 원하는 탱크를 만들자.

킥보드: 일단 수를 만든다(Math.random)

우선 숫자를 무작위로 생성해야 한다. 구글링하니 아래의 함수가 나왔다.
Math.random()
"Cmd + 클릭"을 하면 d.ts 파일이 열린다. 여기서 함수의 파라미터, 리턴값, 개발자의 코멘트를 볼 수 있다.


코멘트를 보니 해당 함수는 0에서 1 사이의 랜덤한(pseudorandom, 의사 난수) 수를 반환한다고 한다.

실제로 확인해보자.

난수가 잘 생성되고 있다. 하지만 소숫점을 길게 보는 건 복잡하니 한 자리 수만 반환하게 하자.

// 소수 부분을 버리고 정수 부분을 반환한다.
Math.floor(숫자)

// 1. 난수의 정수 부분을 한 자리 수로 만들고
// 2. 정수 부분만 반환한다.
Math.floor(Math.random() * 10)

이제 컴퓨터와 사용자의 수를 각각 만들고 이를 프린트해보자. 숫자가 더 큰 쪽이 승자이다.

이번엔 사용자가 이겼다.

자전거: 승자 선언도 프로그래밍하기 (비교연산자)

승자를 판단하려면 두 수를 비교를 해야 한다. 이때는 if문(if statement)를 사용하자. 기본적인 문법은 아래와 같다.

if (조건) {
	만족될 때 실행할 코드
} else {
	조건 위배 시 실행할 코드
}

이를 이용해 사용자의 숫자가 클 때와 그렇지 않을 때를 나누면 다음과 같다.

if (myNumber > cpuNumber) {
  console.log("I won")
} else {
  console.log("Cpu won")
}

하지만 이 경우 사용자와 컴퓨터의 수가 같더라도 컴퓨터가 이긴 것으로 처리된다. 비긴 상황을 만들려면 첫 번 째 조건이 위배된 다음 새로운 조건을 다시 따져야 한다.

if (myNumber > cpuNumber) {
  console.log("I won")
} else if (myNumber === cpuNumber) else {
  console.log("Drew")
} else {
  console.log("Cpu won")
}

같은지 다른지 확인할 땐 반드시 세 글자로

자바스크립트에선 등호를 이용한 표현이 세 가지가 있다.
1. 할당=
2. 타입 무시 비교==
3. 타입 고려 비교===

코딩을 할 땐 언제나 타입을 확정짓는 것이 좋다. 타입을 확정지으면
1. 기존 변수에 다른 타입을 할당하여 기존 코드와 충돌이 일어나는 일을 피할 수 있다.
2. 기존 코드를 살펴볼 때, 파라미터, 반환값의 타입을 보고 함수의 역할과 한계를 쉽게 떠올릴 수 있다.

예를 들어보자.

console.log("1" == 1) // prints true
console.log("1" === 1) // prints false

특정 변수를 비교한 뒤 방정식에 넣으려고 한다고 해보자. ==를 이용해 확인하면 stringnumber로 착각하는 일이 발생할 수 있다. 이를 막기 위해 비교 연산자는 꼭 세 글자로 쓰자.

  • 같은지 확인: ===
  • 다른지 확인: !==

오토바이: 내가 이길 때까지 반복(while loop)

프로그램을 실행했더니 내가 졌다. 그래서 다시 실행했다. 또 졌다. 다시 한 번 실행했을 땐 이겼다. 이 과정을 더 편하게 할 순 없을까?

while 반복문(while loop)를 이용해본자. 기본 구조는 아래와 같다.

// 조건이 위배되면 while loop는 끝난다.
while (조건) {
  만족되면 실행할 코드
}

이를 적용해보자. 조건문에서 myNumbercpuNumber를 비교하기 위해 두 변수를 가변 변수 let으로 while loop 바깥에 할당해둔다.

let myNumber = 0
let cpuNumber = 0

// 사용자가 이김: myNumber > cpuNumber
// 사용자가 못 이김: myNumber <= cpuNumber
while (myNumber <= cpuNumber) {
    myNumber = Math.floor(Math.random() * 10)
    cpuNumber = Math.floor(Math.random() * 10)

    ...
}

실행 결과

자동차: 반복 횟수 지정(for loop)

딱 열 번만 반복하고 이긴 횟수가 많은 쪽이 최종 승자가 되게 하려면 어떻게 해야 할까? 이때는 for 반복문을 사용하자.
for loop의 구조는 아래와 같다.

for (수식1;
     수식2;
     수식3) {
	// 실행될 코드 블록
}

괄호 안에 들어가는 각 수식의 역할을 다음과 같다.
수식1: {}로 감싸진 코드 블록이 실행되기 전에 한 번 실행된다.
수식2: 해당 수식이 만족되면 코드 블록을 실행한다.
수식3: 코드 블록이 실행되고 나면 실행한다.

간단한 예를 보자.

for (let i = 0; 
    i < 10;
    i = i + 1) {
  // ...
}

i = 0으로 설정한다. i < 10을 만족하므로 {}로 감싸진 코드 블록을 실행한다. 이후 i는 기존 i보다 1을 키운 값으로 재설정한다.

마지막 과정은 아래와 같이 축약할 수도 있다.

i = i + 1
i += 1
i++

원하는 횟수만큼 반복키 위해 for loop를 쓸 땐 관례상 세 수식을 한 줄에 쓰고 마지막 수식은 제일 짧은 i++ 형태로 쓴다.

for (let i = 0; i < 10; i++) {
    // ...
}

탱크: 재사용하기 좋게 함수로 정리(refactor)하기

코드를 작성하다보면 한 함수가 굉장히 길어지게 된다. 이는 나중에 해당 코드를 이해하는 데에 큰 장해가 된다. 쉽게 읽히는 코드를 작성하기 위해서 함수를 정리하자.

함수를 정리할 땐 아래의 규칙을 따른다.
1. 한 함수는 한 가지 작업만 한다.
2. 한 함수의 길이는 60줄로 제한한다.

한 함수를 60줄 이내로 작성해야 한다. 이는 A4에 인쇄했을 때 한 페이지 정도의 분량이다. 그보다 더 길어지게 되면 리팩터링을 하여 정리해야 한다.

다만, 한 파일 안의 함수가 너무 많아져도 가독성에 문제가 생긴다. 이때는 비슷한 역할의 함수들을 별도의 파일에 분리하자. 다른 파일에서의 함수를 불러내기 위해선 두 작업이 필요하다.

export(내보내기)

// firstFile.js

function firstFn() {
  // ...
}
function secondFn() {
  // ...
}

export { firstFn, secondFn }

파일의 맨 마지막에 export { firstOne, secondOne }를 작성함으로써 다른 파일에서도 {} 안의 함수들을 들여올 수 있게 한다.

import(들여오기)

import { getTwoNumbers, checkWinner } from './operations.js'

다른 파일의 함수를 사용하기 위해서는 파일의 맨 첫줄에서 import를 해야 한다. import 뒤에는 들여올 함수들을, from 뒤에는 해당 파일의 경로를 적는다. 절대 경로도 괜찮고 상대 경로도 괜찮다.

상대 경로를 적을 땐 아래의 규칙을 사용한다.
.: 현재 폴더(파일 기준)
..: 현재 폴더보다 한 칸 상위 폴더
...: 현재 폴더보다 두 칸 상위 폴더

참고문헌

for loop에 관한 설명은 w3school에서의 설명을 번역하는 정도에 그쳤다.
https://www.w3schools.com/js/js_loop_for.asp

좋은 코드가 무엇인지는 "Nasa's 10 coding rules"로도 불리는 아래의 문서를 따르고 있다.
원본은 나사 내부 문서로 접근이 불가능하다.
Holzmann, The Power of 10: Rules for Developing Safety-Critical Code (NASA/JPL, 2006)

0개의 댓글