BlueNyang
[멀티캠퍼스] 풀스택 개발자 아카데미 (2) - JavaScript
Java 풀스택 아카데미
· 멀티캠퍼스 JAVA 풀스택 개발자 아카데미 6회차 (3편)

[멀티캠퍼스] 풀스택 개발자 아카데미 (2) - JavaScript

BlueNyangBlueNyang
·
·
약 9분
·
# [현대이지웰] JAVA 풀스택 개발자 아카데미 6회차# 멀티캠퍼스it부트캠프# 부트캠프후기# javascript# hoisting# var-let-const# tdz
시리즈·멀티캠퍼스 JAVA 풀스택 개발자 아카데미 6회차(30개의 글)
  • 1.[멀티캠퍼스] 풀스택 개발자 아카데미 (1) - HTML/CSS
  • 2.[멀티캠퍼스] 풀스택 개발자 아카데미 (2) - JavaScript현재
  • 3.[멀티캠퍼스] 풀스택 개발자 아카데미 (3) - JavaScript(2)
  • ···
게시글 이미지

1. JavaScript

자바 스크립트는 '웹 페이지에 생명을 불어넣는' 스크립트 언어이다. 정적인 HTML 구조에 동적인 다음과 같은 기능들을 추가하여 사용자와 상호작용할 수 있게 만들어 준다.

  • HTML 요소의 내용, 속성, 스타일을 동적으로 변경
  • 사용자의 클릭, 마우스 이동 등, 이벤트에 반응하는 동작 구현
  • 서버에 데이터를 보내기 전 사용자가 입력한 값의 유효성 검증

초기 JS는 웹 브라우저에서 간단한 효과를 주는 데에 사용했으나, 이제는 웹의 표준 프로그래밍 언어로 자리잡았다. 현재의 웹 페이지들은 js를 통해 다음과 같은 특징들을 얻게 되었다.

  • 동적인 웹 페이지: 사용자의 행동에 반응하여 컨텐츠를 바꾸거나 애니메이션 효과를 주고나, 서버와 데이터를 주고받는 등의 다향한 기능을 구현한다.
  • 광법위한 활용성: 모든 웹 브라우저에 지원된다. Node.js 통해 서버 사이드나 모바일 앱 등 활용 번위가 넓어졌다.
  • Ajax: 기술의 발전: Ajax(Asynchronou Jsvascript and XML) 기술과 결합하여, 페이지 전체를 새로 고침하지 않고로 서버와 데이터를 교환하며, 동적인 화면 갱신을 할 수 있게 한다.

2. JavaScript의 사용

Javascript는 Interpreter 언어로, HTML 문서 안에서는 세 가지 방식으로 사용할 수 있다.

Note
Interpreter 언어: 코드가 컴파일(실행 파일로 변환하는 과정) 없이 한 줄씩 해석되고 바로 실행되는 언어로, 대표적으로 JS, Python 등이 있다.

2.1. Internal 방식 (내부 스크립트)

HTML Document의 <head> 또는 <body> 태그 안에서 <script> 태그를 만들어 직접 코드를 작성하여 사용할 수 있다. 해당 태그의 type 속성은 일반적으로 <script type="text/javascript">로 작성하여 사용하는데, 최신 HTML은 이를 기본 값으로 인식하기 때문에 생략해도 무관하다. 간단한 코드는 삽입해 사용하거나, 제약 사항으로 인해 .js 파일을 사용할 수 없을 때도 사용할 수 있다.

일반적으로 이러한 Internal 스크립트는 <body>의 마지막에 삽입하는 것이 좋다. html parser(해석기)는 위에서부터 태그를 읽어 내려가다가(파싱) <script>를 만나면, HTML 파싱을 즉시 중단하고, Javascipt 파일을 실행한다.

스크립트를 <head>에 삽입하는 것은 다음과 같은 문제점을 가진다.

  • <head>에 삽입된 스크립트가 방대하면, <body>를 로딩하기 전에 스크립트 코드를 로딩하기 때문에, 빈 화면 로딩이 길어진다.
  • <head>의 스크립트에서 DOM의 요소(HTML 태그 요소)를 조작하려고 하면, 아직 하단의 <body>가 로딩되지 않았기 때문에, 오류가 발생한다.

이 때문에, Internal 스크립트를 <head>에 삽입하는 것은 다른 의도가 없다면 지양하고 있다.

물론 <body>에 삽입하는 것도 문제가 없지는 않다. 스크립트가 실행되기 전까지 버튼을 눌러도 작동하지 않는 등, 상호작용이 지연된다는 것이다. 하지만, HTML 페이지의 주요 내용은 로딩되어 있기 때문에, 로딩 화면을 적절히 넣는다면, 사용자의 사용 경험(UX)이 향상된다.

html
<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8" />
    <title>Internal 방식 script</title>
    <link rel="stylesheet" href="./style.css" />
    <script>
      // head 내의 스크립트
      console.log("head 부분에 삽입된 코드입니다.");
      console.log("이 스크립트는 body가 로딩되기 이전에 실행됩니다.");
      console.log("이 부분의 스크립트가 길면, 로딩이 오래걸릴 수 있습니다.");
    </script>
  </head>
  <body>
    <!-- ... -->
    <script>
      // body 내의 스크립트
      console.log("body 부분에 삽입된 코드입니다.");
      console.log("이 스크립트는 body가 로딩된 후 실행됩니다.");
    </script>
  </body>
</html>
게시글 이미지

이 코드 스니펫과 같이, <head><body>에 삽입된 <script>는 실행이 되는 시점이 조금 다르기 때문에, <body>내의 <script><head>의 내용을 가져와 사용하는 것은 가능하지만, <head><script><body>의 내용을 가져와 실행하는 경우에는 오류가 발생할 수 있다.

2.2. External 방식 (외부 스크립트)

자바스크립트 코드는 별도의 .js파일로 분리하여 저장하고, HTML에서는 <script>src 속성을 사용하여 파일을 불러올 수 있다. 이는 코드의 재사용성과 유지보수의 관점에서 가장 권장되는 방식이다.

js
// script.js
console.log("별도의 .js 파일에서 실행되는 코드입니다.");
html
<!-- index.html -->
<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8" />
    <title>External 방식 예제</title>
    <script src="script.js" defer></script>
  </head>
  <body></body>
</html>
게시글 이미지

이러한 External 방식 또한 Internal과 같이 실행 시점이 동일하다. 특히, external 방식은 <script> 태그를 만나는 시점에서 .js파일을 다운로드 하기 때문에, 너무 큰 .js<head>에 삽입하면, 빈 화면 로딩이 길어진다.

과거에는 많은 js 라이브러리(특히 jQuery)의 공식 문서에서 <head><script>를 통해 코드를 넣으라고 안내했지만, 이는 오래된 방식으로, 현재 권장되는 방법은 2가지 방법을 사용한다.

  • <body> 끝에 배치

    • 가장 고전적이고 확실한 방법이다.
    • 페이지의 모든 시각적 요소가 먼저 사용자에게 표시된 후, .js를 불러오기 때문에 빈 화면 로딩이 최소화된다.
  • defer 속성 사용 (가장 권장)

    • defersrc를 사용하는 <script> 태그에 사용가능한 속성으로, 가장 현대적인 방식
    • defer를 사용하면, <script><head>에 삽입해도 html 렌더링을 멈추지 않는다. 페이지를 그리면서 script를 다운로드하고, 페이지를 모두 그리면 코드를 실행한다.
    • 사용 예시:
js
<script src="https://code.jquery.com/jquery-3.7.1.min.js" defer></script>

2.3. Inline 방식 (인라인 스크립트)

HTML 태그의 이벤트 속성(onclick, onload 등)에 직접 자바스크립트 코드를 작성하는 방식으로, 코드의 양이 매우 적을 때 사용되며, 구조와 동작의 분리 원칙에 위배되어 최근에는 잘 사용하지 않는다.

html
<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8" />
    <title>Inline 방식 예제</title>
    <script type="text/javascript">
      function start() {
        console.log("start() 함수에 삽입된 스크립트 입니다.");
      }
    </script>
  </head>
  <body onLoad="start()"></body>
</html>
게시글 이미지

이후 진행되는 모든 코드는 External 방식으로 삽입되어 진행되며, <head>defer 속성이 들어간 <script>태그를 넣고 실행한다.

3. 데이터 입출력

자바스크립트는 사용자에게 정보를 보여주거나(출력), 사용자로부터 정보를 받을(입력) 수 있는 간단한 내장 함수들을 제공한다.

3.1. 데이터 출력

  • alert(내용): 사용자에게 내용을 담은 경고창을 띄움
게시글 이미지
  • document.write(내용): 웹 페이지의 본문에 직접 내용을 출력한다.
  • 해당 메서드(함수)는 웹 페이지의 로딩과 성능에 심각한 악영향을 미칠 수 있기 때문에 사용을 피해야 한다.
  • document.write()는 기존의 문서 내용을 지우고 새로운 내용을 작성하기 때문에 현재 문서의 내용이 사라지는 문제를 야기할 수 있다.
  • 특히, defer를 사용하는 스크립트에서는 사용할 수 없다.
게시글 이미지
  • console.log(내용): 브라우저의 개발자 도구 콘솔에 메시지를 출력.
  • console.log()는 특히, 개발 과정에서 변수 값을 확인하는 등 디버깅 목적으로 가장 많이 사용
게시글 이미지

3.2. 데이터 입력

  • confirm(내용): 확인취소버튼이 있는 대화 상자를 띄우며, 사용자가 확인을 누르면 true, 취소를 누르면 false를 반환함.
  • prompt(내용, [기본값]): 사용자에게 텍스트를 입력받을 수 있는 대화상자를 띄우며, 입력된 값을 문자열 형태로 반환한다.

    • 입력 값을 숫자와 같은 다른 형태로 사용하려면 형변환을 해주어야 한다.
게시글 이미지
게시글 이미지

4. 핵심 개념

4.1. 변수

변수는 데이터를 저장하기 위해 마련된 메모리 공간이다. 자바스크립트에서는 변수를 선언하기 위해 var, let, const 키워드를 사용한다.

4.1.1 var(비권장)

var(비권장): ES6 이전에 사용되던 변수 선언 키워드 이다.

  • 함수 스코프(Function-scoped): 함수(function) 내에서 선언된 var변수는 함수 안에서면 유효 함.
  • 중복 선언 가능: 같은 이름으로 여러 번 선언하면, 에러가 발생하지 않고, 덮어씀.
  • Hoisting: 변수 선언이 Scope 최상단(함수의 최상단)으로 끌어 올려지는 현상이 있다. 즉, 선언하지 전에 사용해도 오류는 나지 않고, undefined를 반환한다.
js
function varTest() {
  var x = 1;
  if (true) {
    var x = 2;
    console.log(x); // 2가 출력됨
  }
  console.log(x); // 2가 출력됨.
}

console.log(myVar); // undefine 출력(오류가 나지 않음)
var myVar = "Hello";

이러한 var의 특징들은 개발자로 하여금 버그를 유발하더라도 원인을 쉽게 찾기 어렵고, 가독성을 해치게 된다. 특히, 위의 Snippet에서와 같이 varforif의 블록({}) 내에서 변수를 덮어쓰면 블록 밖의 값도 바뀌어 버리기 때문에 프로그램의 결과를 예측하기 어려워질 수 있다.

4.1.2. let: 새로운 표준 변수 선언

letvar의 단점을 보완하기 위해 ES6(ECMAScript 2015)에서 도입된 변수 선언 방법이다. let은 다음과 같은 특징들을 가진다.

  • 블록 스코프(block-scope): let으로 선언된 변수는 자신이 선언된 코드 블록({ }) 안에서만 유효하다.

    • 즉 변수의 유효 범위가 명확하고, 코드의 예측 가능성을 높여주는 효과를 가진다.
  • 재선언금지: 같은 Scope 내에서 동일한 이름으로 변수를 다시 선언할 수 없다.

    • 이를 통해 변수의 이름이 같아 발생할 수 있는 버그를 방지한다.
  • 재할당 가능: 변수에 다른 값을 다시 할당할 수 있다.
js
function letTest() {
  let x = 1;
  if (true) {
    let x = 2; // if 내에서의 새로운 x
    console.log(x); // 2 출력
  }
  console.log(x); // 1 출력

  if (true) {
    x = 3; // 선언이 아니라 원래 있는 x를 그대로 사용
  }
  console.log(x); //3 출력
}

let y = "hi";
//let y = "world"; // !!문법 오류 발생!!

만약 변수에 값이 변할 가능성이 있다면 let의 사용을 권장한다.

4.1.2. const: 불변의 상수 선언

const 역시 ES6에서 함께 도입된 상수(Constant) 선언 방식이다. 즉, 변하지 않는 값을 선언할 때 사용한다.

  • 블록 스코프: let과 동일한 블록 스코프를 가짐
  • 재할당 절대 금지: 선언과 함께 값이 할당해야 하며, 이후 다른 값으로 재할당할 수 없음.
  • 선언 시 초기화 필수: 반드시 선언과 동시에 값을 할당해야 함
js
const PI = 3.14159;
// PI = 4; // 문법 오류 발생

// const a; //할당하지 않아 오류 발생
Warning
const는 변수에 할당된 메모리 주소(참조)를 불변으로 만드는 것입니다. 따라서 객체나 배열을 할당하면, 그 주소 자체는 바꿀 수 없지만(재할당 불가), 그 주소가 가리키는 객체의 내부 속성이나 배열의 요소는 변경할 수 있다.
js
const person = {
  name: "Alice",
};
person.name = "Bob"; // 가능!
console.log(person.name); // "Bob"

// person = { name: "Charlie" }; // 불가능! (새로운 객체로 재할당 불가)

기본적으로 모든 변수는 const로 선언하고, 재할당이 필요한 경우에만 let으로 변경하는 것을 권장한다. 이렇게 하면 코드의 안정성과 예측 가능성이 크게 향상되기 때문이다.

4.2. 호이스팅(Hoisting)

호이스팅(Hoisting): "끌어올리다"라는 뜻으로, 자바스크립트 엔진이 코드를 실행하기 전에 변수와 함수의 선언을 해당 스코프의 최상단으로 끌어올리는 것처럼 동작하는 현상이다.

var의 호이스팅: var로 선언된 변수는 스코프 최상단으로 끌어올려진 후 undefined로 초기화됩니다. 따라서 선언문 이전에 변수에 접근해도 에러가 발생하지 않고 undefined가 출력된다.

let, const의 호이스팅: letconst로 선언된 변수도 호이스팅이 된다. 하지만 var처럼 undefined로 초기화되지 않습니다. 대신, 스코프의 시작 지점부터 변수의 선언문까지 일시적 사각지대(Temporal Dead Zone, TDZ)에 놓인다. 하지만, var과 달리, 이 TDZ 구간에서 해당 변수에 접근하려고 하면 참조 에러(ReferenceError)가 발생하기 때문에, 혹여 발생할 수 있는 버그나 오류를 방지할 수 있다.

4.3. 데이터 타입 (Data Type)

자바스크립트는 변수에 값이 할당될 때 데이터 타입이 결정되는 동적 타이핑(Dynamic Typing) 언어이다.

원시(Primitive) 타입:

  • String: 문자열 (예: "안녕하세요", 'Hello')
  • Number: 숫자 (정수, 실수 모두 포함)
  • Boolean: 논리값 (true 또는 false)
  • null: '값이 없음'을 의도적으로 명시한 상태
  • undefined: 변수를 선언만 하고 값을 할당하지 않은 상태

참조(Reference) 타입:

  • Object: 객체. 배열, 함수 등도 모두 객체에 속함

데이터 형 변환 (Type Conversion):

  • 문자열을 숫자로, 또는 숫자를 문자열로 바꾸는 등 데이터의 타입을 변환하는 것.

    • Number(값) 또는 parseInt(값): 문자열을 숫자로 변환
    • parseInt는 정수로, Number는 실수까지 변환
    • String(값) 또는 값.toString(): 숫자를 문자열로 변환

5. 제어문

5.1. 조건문 (Conditional Statements)

주어진 조건의 참/거짓 여부에 따라 다른 코드를 실행하는 제어문

  • if...else if...else: 가장 일반적인 조건문
  • switch: 하나의 변수 값을 여러 값과 비교할 때 유용하다

    • case 끝에는 break를 작성하여 불필요한 실행을 막는 것이 중요
js
let fruit = prompt("어떤 과일을 좋아하세요?");

switch (fruit) {
  case "사과":
    document.write("사과는 빨간색입니다.");
    break;
  case "바나나":
    document.write("바나나는 깁니다.");
    break;
  case "오렌지":
    document.write("오렌지는 둥급니다.");
    break;
  default:
    document.write(fruit + "에 대한 정보가 없습니다.");
}

5.2. 반복문 (Loop Statements)

특정 코드를 여러 번 반복해서 실행할 때 사용

  • for: 정해진 횟수만큼 반복할 때 주로 사용합니다.

    • for (초기값; 조건식; 증감식) 형태로 구성
  • while: 조건이 참인 동안 계속 반복합니다. 조건이 처음부터 거짓이면 한 번도 실행되지 않을 수 있다.
  • do...while: while문과 비슷하지만, 코드를 최소 한 번은 실행한 뒤 조건을 검사
  • for...in: 객체의 속성들을 순회할 때 사용
  • forEach: 배열의 각 요소를 순회하며 콜백 함수를 실행
js
const rows = 5;
const cols = 5;

const table = document.createElement("table");

for (let i = 0; i < rows; i++) {
  const tr = document.createElement("tr");
  for (let j = 0; j < cols; j++) {
    const td = document.createElement("td");
    td.textContent = i * cols + j + 1;
    tr.appendChild(td);
  }
  table.appendChild(tr);
}
document.body.appendChild(table);
게시글 이미지

JAVA 풀스택 아카데미 과정 6회차

아무래도 전공자이기도 하고, 이미 배우며 프로젝트를 진행해본 경험이 있다보니, 아쉬운 부분이 더 눈에 띄는 것 같다.

  • 실습을 진행하는 부분이나, 전체적인 진행은 비전공자도 어느정도 따라올 수 있는 듯하고, 이부분은 좋다고 생각했다.
  • var의 사용 권장 수업의 실습 과정에서 최신 키워드인 constlet 대신, var를 사용했다. 이에 더해 명시적으로 변수를 선언 시에는 var를 사용하라는 문장에서 꽤나 충격적이었다. ES6 최신 JS에서는 기본적으로 var를 권장하지 않으며, letconst가 모범 사례로 여겨진다. 초보자들에게 var의 사용이 쉬운 것은 맞다. 하지만 이는 let만 사용하는 것으로 충분히 보완할 수 있다. 또한, var을 사용하는 습관을 들인다면, 향후 실제 서비스 개발에서도 사용하게 될 가능성이 매우 농후하다. 이는 곧, 디버깅 능력이 비교적 부족한 초보 개발자에게 악영향을 미칠 수 있을 지도 모른다. 이 점은 꽤 아쉬웠다.
BlueNyang
작성자BlueNyang
라이선스
CC BY NC
BlueNyang

BlueNyang

BlueNyang의 개발 log

카테고리

  • Development
  • Framework
  • Language
  • Dev Tools
  • DevOps & Infra
  • Studies

페이지

© 2026 BlueNyang. All rights reserved.

Made with Nuxt.js and Directus