본문으로 건너뛰기
Advertisement

1.4 Hello World

JavaScript 실행 방법 3가지

JavaScript 코드를 실행하는 방법은 크게 3가지가 있습니다.


방법 1: 인라인 스크립트

HTML 파일 안에 <script> 태그를 직접 작성합니다.

<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<title>Hello World</title>
</head>
<body>
<h1 id="greeting">안녕하세요!</h1>

<script>
// 인라인 JavaScript
console.log("Hello, World!");

// DOM 조작
const h1 = document.getElementById('greeting');
h1.textContent = 'Hello, JavaScript!';
h1.style.color = 'blue';
</script>
</body>
</html>

장점: 별도 파일 없이 빠르게 테스트 가능 단점: 코드가 길어지면 HTML이 복잡해짐, 캐싱 불가


방법 2: 외부 스크립트 파일

JavaScript 코드를 별도의 .js 파일로 분리합니다.

<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<title>Hello World</title>
</head>
<body>
<h1 id="greeting">안녕하세요!</h1>
<button id="btn">클릭하세요</button>

<!-- 외부 스크립트 로드 -->
<script src="app.js" defer></script>
</body>
</html>
// app.js
console.log("외부 스크립트 로드됨!");

const greeting = document.getElementById('greeting');
const btn = document.getElementById('btn');

btn.addEventListener('click', () => {
greeting.textContent = '버튼을 클릭했습니다!';
});

장점: 코드 분리, 브라우저 캐싱 가능, 재사용 가능 단점: 추가 HTTP 요청 필요 (단, 캐싱으로 완화)


방법 3: Node.js로 직접 실행

터미널에서 node 명령으로 실행합니다.

// hello.js
console.log("Hello, World!");
console.log("Node.js 버전:", process.version);

const name = "JavaScript";
console.log(`안녕하세요, ${name}!`);
# 실행
node hello.js

# 출력
# Hello, World!
# Node.js 버전: v20.11.0
# 안녕하세요, JavaScript!

<script> 태그 위치와 defer/async

<script> 태그의 위치와 속성은 페이지 로딩 성능에 큰 영향을 미칩니다.

<head> 안에 위치 (비권장)

<head>
<!-- 문제: HTML 파싱이 중단되고 스크립트를 다운로드/실행 후 재개 -->
<!-- DOM이 아직 없으므로 document.getElementById 같은 코드가 null 반환 -->
<script src="app.js"></script>
</head>

</body> 직전 위치 (전통적 방법)

<body>
<!-- HTML 내용들 -->
<h1>Hello</h1>

<!-- DOM이 준비된 후 실행 -->
<script src="app.js"></script>
</body>

장점: DOM이 준비된 후 실행 단점: HTML이 모두 로드된 후에야 스크립트 다운로드 시작

defer 속성 (권장)

<head>
<!-- HTML 파싱과 병렬로 다운로드, HTML 파싱 완료 후 실행 -->
<!-- DOMContentLoaded 이벤트 직전에 실행 -->
<script src="app.js" defer></script>
</head>
  • HTML 파싱을 막지 않음
  • 여러 스크립트의 경우 순서 보장
  • DOMContentLoaded 이벤트 전에 실행

async 속성

<head>
<!-- HTML 파싱과 병렬로 다운로드, 다운로드 완료 즉시 실행 (파싱 중단) -->
<script src="analytics.js" async></script>
</head>
  • 다운로드 완료 즉시 실행 (HTML 파싱 일시 중단)
  • 여러 스크립트의 경우 순서 미보장
  • 다른 스크립트/DOM에 의존하지 않는 독립적인 스크립트에 적합

비교 정리

일반 <script>:
HTML: ----파싱---||---대기---||---계속---
JS: ▼다운로드▼실행▼

defer:
HTML: ----파싱-------------------완료→
JS: ▼다운로드--------▼실행↑

async:
HTML: ----파싱---||---대기---||---계속---
JS: ▼다운로드▼▼실행↑

규칙: 대부분의 경우 defer를 사용하고, <head> 안에 배치하는 것이 최신 권장 방식입니다.


console 메서드 완전 가이드

JavaScript 개발에서 가장 많이 사용하는 디버깅 도구는 console입니다.

기본 출력 메서드

console.log('일반 메시지');         // 일반 로그
console.info('정보 메시지'); // 정보 (log와 동일)
console.warn('경고 메시지'); // 노란색 경고
console.error('오류 메시지'); // 빨간색 오류
console.debug('디버그 메시지'); // 디버그 (verbose)

스타일 적용 (브라우저)

console.log('%c화려한 텍스트', 'color: blue; font-size: 20px; font-weight: bold');
console.log('%c에러!', 'color: white; background: red; padding: 2px 5px');

객체/배열 표시

const user = { name: '김철수', age: 25, role: 'developer' };
console.log(user); // {name: '김철수', age: 25, role: 'developer'}
console.dir(user); // 객체의 속성을 트리 구조로 표시

const users = [
{ id: 1, name: '김철수', score: 85 },
{ id: 2, name: '이영희', score: 92 },
{ id: 3, name: '박민수', score: 78 },
];
console.table(users); // 표 형식으로 표시

성능 측정

// time/timeEnd
console.time('정렬 시간');
const arr = Array.from({ length: 100000 }, () => Math.random());
arr.sort((a, b) => a - b);
console.timeEnd('정렬 시간'); // 정렬 시간: 15.234ms

// count
function processItem(item) {
console.count('processItem 호출'); // 호출 횟수 카운트
}
processItem('a'); // processItem 호출: 1
processItem('b'); // processItem 호출: 2
processItem('c'); // processItem 호출: 3
console.countReset('processItem 호출'); // 카운트 리셋

그룹화 및 추적

// 그룹화
console.group('사용자 처리');
console.log('이름 검증...');
console.log('이메일 검증...');
console.group('주소 검증');
console.log('시/도 확인...');
console.log('상세 주소 확인...');
console.groupEnd();
console.groupEnd();

// 스택 트레이스
function foo() {
function bar() {
console.trace('여기서 호출됨');
}
bar();
}
foo();
// 출력: 여기서 호출됨
// bar @ ...
// foo @ ...
// ...

조건부 출력

const value = 42;
console.assert(value > 100, '값이 100보다 작습니다!', value);
// 조건이 false일 때만 출력: 값이 100보다 작습니다! 42

ES 모듈로 Hello World

현대적인 방식으로 모듈을 사용한 예시:

// greet.js
export function greet(name) {
return `Hello, ${name}!`;
}

export const DEFAULT_NAME = 'World';
// main.js
import { greet, DEFAULT_NAME } from './greet.js';

console.log(greet(DEFAULT_NAME)); // Hello, World!
console.log(greet('JavaScript')); // Hello, JavaScript!
<!-- index.html - type="module" 필수 -->
<script type="module" src="main.js"></script>

또는 Node.js에서:

node main.js  # package.json에 "type": "module" 필요

첫 번째 인터랙티브 페이지

실제로 동작하는 간단한 예제를 만들어봅니다.

<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<title>나의 첫 JavaScript</title>
<style>
body { font-family: Arial, sans-serif; max-width: 600px; margin: 50px auto; }
button { padding: 10px 20px; font-size: 16px; cursor: pointer; }
#output { margin-top: 20px; padding: 15px; background: #f0f0f0; border-radius: 8px; }
</style>
</head>
<body>
<h1>Hello, JavaScript!</h1>
<input type="text" id="nameInput" placeholder="이름을 입력하세요">
<button id="greetBtn">인사하기</button>
<div id="output">여기에 결과가 표시됩니다.</div>

<script defer>
const input = document.getElementById('nameInput');
const btn = document.getElementById('greetBtn');
const output = document.getElementById('output');

btn.addEventListener('click', () => {
const name = input.value.trim();
if (name) {
output.textContent = `Hello, ${name}! JavaScript에 오신 것을 환영합니다!`;
output.style.color = 'green';
} else {
output.textContent = '이름을 입력해주세요!';
output.style.color = 'red';
}
});

// Enter 키 지원
input.addEventListener('keypress', (e) => {
if (e.key === 'Enter') btn.click();
});
</script>
</body>
</html>

고수 팁

console.log 대신 디버거 사용

실전에서는 console.log 보다 VS Code의 내장 디버거나 브라우저 DevTools 중단점(breakpoint)을 사용하는 것이 더 효율적입니다.

// 이것보다
console.log('변수값:', someComplexObject);

// 이게 더 좋음: debugger 키워드로 중단점 설정
debugger; // 개발자 도구가 열려 있을 때 실행이 이 줄에서 멈춤

프로덕션에서 console 제거

빌드 도구(Vite, webpack)를 사용하면 프로덕션 빌드에서 console.log를 자동 제거할 수 있습니다:

// vite.config.js
export default {
build: {
minify: 'terser',
terserOptions: {
compress: {
drop_console: true, // 프로덕션에서 console.* 제거
drop_debugger: true,
},
},
},
};
Advertisement