PHpullh

JAVASCRIPT · 심층 가이드

JavaScript Hello World 완전 정리

console.log 한 줄에서 시작해 명령행 인자와 환경 변수 읽기까지, JavaScript 실행 환경이 프로그램에 무엇을 건네주는지 10개 예제로 확인합니다.

주제 10개 · 예제 코드 포함 · 최종 수정 2026-09-03 · 작성 pullh 편집팀

JavaScript의 첫 프로그램은 언어보다 실행 환경을 먼저 만나게 합니다. 같은 console.log('Hello')도 브라우저에서는 개발자 도구 콘솔에, Node.js에서는 터미널 표준 출력에 나갑니다. 파일을 읽거나 명령행 인자를 받는 일은 언어 명세가 아니라 런타임이 제공하는 기능이라, 브라우저에는 아예 존재하지 않습니다. 이 구분을 초반에 잡아 두면 나중에 '왜 이 코드는 Node에서만 되는가' 같은 질문에 시간을 덜 씁니다. 이 문서의 예제들은 Node 실행을 전제로 합니다.

Hello World 출력과 변수 값을 같이 출력으로 출력 함수의 기본형을 확인한 뒤 템플릿 문자열 인사로 넘어가면, 문자열을 +로 이어 붙이던 습관이 왜 백틱으로 바뀌었는지가 한눈에 보입니다. 뒤쪽의 명령행 인자 읽기와 환경 변수 읽기, 버전 정보 출력은 성격이 다릅니다. 셋 모두 process 객체를 통해 바깥 세계의 값을 프로그램 안으로 들여오는 예제이고, 설정을 코드에 하드코딩하지 않는 첫걸음이기도 합니다.

명령행 인자에서 거의 모두가 한 번은 헤맵니다. process.argv의 0번은 node 실행 파일 경로, 1번은 실행한 스크립트 경로이고 사용자가 입력한 첫 인자는 2번부터입니다. process.argv[0]을 이름으로 쓰면 엉뚱한 값이 찍힙니다. 환경 변수도 성격이 하나 있습니다. process.env의 값은 언제나 문자열이라, 숫자로 쓰려면 Number()로 변환해야 하고 없는 키는 undefined가 되므로 기본값 처리를 함께 붙여 두는 편이 낫습니다.

01Hello World 출력

문자열 하나를 console.log로 표준 출력에 내보내고 끝에 줄바꿈을 붙입니다. 실행 환경이 제대로 잡혔는지 확인하는 첫 코드로 씁니다. console.log는 표준 출력, console.error는 표준 오류로 나가므로 파이프로 걸러 낼 때 둘이 구분됩니다.

JavaScript code

// Hello World 출력
console.log("Hello, World 1!");
알아두면 좋은 점

console.log는 첫 인자에 %s나 %d 같은 형식 지정자를 쓰면 뒤에 넘긴 값들이 그 자리에 순서대로 들어갑니다.

자주 하는 실수

출력을 파이프로 넘길 때 console.error로 찍은 내용은 함께 흐르지 않습니다. 진단 메시지와 결과 데이터를 섞으면 뒤에서 걸러 내기 어려워집니다.

02변수 값을 같이 출력

greet가 템플릿 리터럴로 이름을 문자열 사이에 끼워 넣어 Hello, Ada를 만들고, 그 반환값을 출력합니다. 형식이 고정된 문구를 조립할 때 쓰는 방식입니다. ${} 안의 값은 문자열로 변환되므로 객체를 넣으면 [object Object]가 됩니다.

JavaScript code

// 변수 값을 같이 출력
function greet(name) {
  return `Hello, ${name}`;
}
console.log(greet("Ada"));
알아두면 좋은 점

템플릿 리터럴은 줄바꿈을 그대로 담아 여러 줄 문자열을 만들 수 있고, ${} 안에는 값이 되는 표현식이면 무엇이든 넣을 수 있습니다.

자주 하는 실수

${obj}는 문자열 변환을 거쳐 [object Object]가 됩니다. 내용을 보려면 JSON.stringify를 쓰거나 값을 따로 인자로 넘겨야 합니다.

03함수로 인사 만들기

배열 names를 for...of로 돌며 이름 세 개를 한 줄씩 출력합니다. 순서대로 처리하면서 필요하면 break로 멈출 수 있는 반복에 적합합니다. for...in은 값 대신 인덱스 문자열을 주기 때문에 배열 순회에는 맞지 않습니다.

JavaScript code

// 함수로 인사 만들기
const names = ["Ada", "Grace", "Linus"];
for (const name of names) console.log(name);
알아두면 좋은 점

for...of를 names.entries()와 함께 쓰면 인덱스와 값을 한 번에 구조 분해로 받아 낼 수 있어 별도 카운터가 필요 없습니다.

자주 하는 실수

for...of는 일반 객체에는 쓸 수 없어 순회 가능하지 않다는 오류가 납니다. 객체를 돌려면 Object.entries를 먼저 거쳐야 합니다.

04배열을 순회하며 인사

APP_ENV가 설정돼 있으면 그 값을, 없으면 노드 버전 문자열을 출력합니다. 설정 주입 여부에 따라 동작이 갈리는 스크립트에서 쓰는 형태입니다. ??는 빈 문자열이나 0도 값으로 인정하므로 ||와 달리 빈 값이 기본값으로 바뀌지 않습니다.

JavaScript code

// 배열을 순회하며 인사
console.log(process.env.APP_ENV ?? process.version);
알아두면 좋은 점

process.version은 앞에 v가 붙은 문자열이라, 버전을 숫자로 비교하려면 process.versions.node를 점 단위로 쪼개는 편이 편합니다.

자주 하는 실수

환경 변수 이름을 오타 내도 오류 없이 undefined가 되어 항상 기본값 경로로 흐릅니다. 설정이 반영되지 않는 이유를 찾기 어려워집니다.

05명령행 인자 읽기

명령행 인자를 읽는 대신 고정된 문구를 그대로 찍습니다. 실제 인자는 process.argv에 배열로 들어오고 앞 두 항목은 실행 파일과 스크립트 경로가 차지합니다. console.log에 값을 여러 개 넘기면 공백으로 이어져 한 줄로 나옵니다.

JavaScript code

// 명령행 인자 읽기
console.log("Hello, World 5!");
알아두면 좋은 점

process.argv의 첫 항목은 노드 실행 파일, 두 번째는 스크립트의 절대 경로라 실제 인자는 세 번째부터 시작합니다.

자주 하는 실수

인자에 공백이 들어가면 셸이 여러 개로 쪼개 넘깁니다. 파일 이름처럼 공백이 있을 수 있는 값은 따옴표로 감싸야 하나의 인자로 도착합니다.

06템플릿 문자열 인사

백틱 문자열 덕분에 따옴표와 +를 섞지 않고도 값이 제자리에 들어갑니다. 줄바꿈도 그대로 살아 있어 SQL이나 HTML 조각을 담기에 편합니다. 다만 끼워 넣은 값은 자동으로 이스케이프되지 않으니 사용자 입력이라면 따로 처리해야 합니다.

JavaScript code

// 템플릿 문자열 인사
function greet(name) {
  return `Hello, ${name}`;
}
console.log(greet("Ada"));
알아두면 좋은 점

태그드 템플릿을 쓰면 고정 문자열과 삽입 값을 나눠 받을 수 있어, 이스케이프나 서식 처리를 함수 한곳에 모을 수 있습니다.

자주 하는 실수

사용자 입력을 템플릿 리터럴로 HTML에 끼워 넣으면 태그가 그대로 해석되어 스크립트 삽입에 노출됩니다. 문자열 조립 대신 텍스트 노드로 넣어야 합니다.

07유니코드 메시지 출력

이름 목록을 순회하며 각 요소를 그대로 표준 출력에 씁니다. 출력 자체는 UTF-8이라 한글이나 이모지도 깨지지 않지만, 문자열 length는 코드 단위 기준이라 이모지 하나가 2로 세어집니다. for...of를 문자열에 쓰면 코드 포인트 단위로 돕니다.

JavaScript code

// 유니코드 메시지 출력
const names = ["Ada", "Grace", "Linus"];
for (const name of names) console.log(name);
알아두면 좋은 점

이모지처럼 코드 단위 두 개로 표현되는 문자를 세려면 [...str].length나 Intl.Segmenter를 써야 실제 글자 수에 가까워집니다.

자주 하는 실수

slice는 코드 단위 기준이라 서로게이트 쌍 가운데를 자르면 깨진 문자가 남습니다. 미리보기 문자열을 만들 때 자주 겪는 문제입니다.

08환경 변수 읽기

환경 변수 하나를 읽고 값이 비어 있을 때만 process.version으로 대체합니다. 환경 변수는 프로세스가 시작할 때 복사되므로 실행 중에 셸에서 바꿔도 반영되지 않습니다. 정의되지 않은 이름을 읽어도 오류 없이 undefined가 돌아옵니다.

JavaScript code

// 환경 변수 읽기
console.log(process.env.APP_ENV ?? process.version);
알아두면 좋은 점

여러 환경 변수를 확인할 때는 process.env를 통째로 찍기보다 필요한 키만 골라 객체로 만들어야 비밀 값이 로그에 섞이지 않습니다.

자주 하는 실수

실행 중에 process.env를 바꿔도 이미 그 값을 읽어 둔 모듈에는 반영되지 않습니다. 설정은 시작 시점에 한 번 읽는 편이 예측하기 쉽습니다.

09컬렉션 요약 출력

컬렉션을 요약하는 대신 짧은 문자열 한 줄만 찍습니다. 배열이나 객체를 넘기면 console.log가 구조를 펼쳐 보여 주지만, 중첩이 깊으면 안쪽이 [Object]로 잘립니다. 전부 보려면 JSON.stringify나 util.inspect의 깊이 옵션이 필요합니다.

JavaScript code

// 컬렉션 요약 출력
console.log("Hello, World 9!");
알아두면 좋은 점

Node에서는 console.dir(obj, { depth: null })로 중첩 깊이 제한 없이 객체 전체를 펼쳐 볼 수 있습니다.

자주 하는 실수

큰 배열을 그대로 출력하면 콘솔이 앞뒤 일부만 보여 주고 나머지를 생략합니다. 생략된 곳에 원인이 있으면 로그만 보고는 알아챌 수 없습니다.

10버전 정보 출력

버전 대신 이름을 받아 인사 문자열을 돌려주는 함수를 정의하고 Ada로 호출합니다. 실행 중인 런타임 정보가 필요하면 process.version이나 process.versions를 읽습니다. 함수 선언은 호이스팅되므로 console.log보다 아래에 두어도 동작합니다.

JavaScript code

// 버전 정보 출력
function greet(name) {
  return `Hello, ${name}`;
}
console.log(greet("Ada"));
알아두면 좋은 점

런타임 정보는 process.versions에 노드와 V8 버전이 함께 담겨 있어, 어떤 엔진 위에서 도는지 한 번에 확인할 수 있습니다.

자주 하는 실수

함수 선언은 끌어올려지지만 const에 담은 함수 표현식은 그렇지 않습니다. 순서를 바꿔도 되리라 믿고 옮기면 참조 오류가 납니다.

정리하며

  • 브라우저와 Node.js에서 쓸 수 있는 기능이 다르다는 전제를 처음부터 갖고 시작합니다
  • 문자열 조립은 + 연결 대신 백틱 템플릿 문자열을 기본 도구로 삼습니다
  • 명령행 인자는 process.argv의 인덱스 2번부터 읽어야 실제 입력값을 얻습니다
  • process.env 값은 항상 문자열이므로 형 변환과 기본값 처리를 함께 작성합니다

더 깊이 들어가고 싶다면 JavaScript 학습 라이브러리에서 다른 주제 가이드를 이어서 보거나, 언어 비교에서 같은 개념이 다른 언어에서 어떻게 표현되는지 확인해 보세요.