JavaScript 변수 설명: var vs let vs const, 스코프 및 모범 사례

目次

1. 소개

JavaScript는 웹 개발에서 가장 널리 사용되는 프로그래밍 언어 중 하나입니다. 특히 프론트엔드 개발에서는 인터랙티브한 웹 페이지를 만들기 위해 필수적입니다. 이러한 맥락에서 변수는 프로그램 내 데이터 관리에 중요한 역할을 합니다.

이 글에서는 JavaScript 변수에 대해 기본 개념부터 고급 주제까지 자세히 설명합니다. 구체적으로 변수 선언 방법, 스코프 개념 이해, 네이밍 규칙, 흔히 발생하는 오류 방지 등을 실용적인 코드 예제와 함께 배울 수 있습니다.

1.1 이 글에서 배울 내용

이 글을 읽으면 다음과 같은 지식과 기술을 습득하게 됩니다.

  1. JavaScript에서 변수의 기본 개념과 역할 이해
  2. var, let, const의 차이점과 올바른 사용법 학습
  3. 스코프와 생명주기를 효과적으로 관리하는 방법
  4. 실제 코드 예제를 통해 변수를 활용하는 실전 기술 적용
  5. 흔히 발생하는 오류 원인을 파악하고 해결 방법 습득

1.2 대상 독자

  • JavaScript 기초를 배우고 싶은 초보자
  • 코딩 경험은 있지만 변수 차이점과 스코프에 대해 더 깊이 알고 싶은 중급 학습자
  • 코딩 실수를 줄이고 프로그램을 보다 효율적으로 설계하고 싶은 모든 사람

이 가이드는 코드 예제로 개념을 설명하므로 초보자가 막히지 않도록 돕습니다. 또한 오류 방지 팁과 FAQ 섹션을 포함해 중급 학습자도 실용적인 적용 지식을 얻을 수 있도록 구성했습니다.

다음 섹션에서는 “변수”가 무엇인지 자세히 살펴보겠습니다.

2. JavaScript에서 변수란?

JavaScript에서 변수는 데이터를 일시적으로 저장하고 필요할 때 재사용할 수 있도록 이름을 붙인 컨테이너입니다. 변수를 사용하면 프로그램 내 데이터 관리를 보다 효율적으로 할 수 있습니다.

2.1 변수의 역할은?

프로그래밍에서 변수는 정보를 저장하는 “상자”와 같습니다. 데이터를 상자에 넣고 꺼내면서 프로그램 상태를 관리하고 계산을 수행할 수 있습니다.

예를 들어, 다음 코드는 변수를 사용해 메시지를 출력합니다.

let greeting = "Hello!";
console.log(greeting);

위 코드에서:

  • 변수 greeting은 문자열 "Hello!" 를 저장합니다.
  • console.log()는 해당 변수의 내용을 콘솔에 출력합니다.

이처럼 변수는 프로그램에서 데이터를 동적으로 조작할 수 있게 해 줍니다.

2.2 JavaScript 변수의 주요 특징

JavaScript 변수는 다음과 같은 특징을 가집니다.

  1. 동적 타이핑
  • JavaScript에서는 변수의 타입(숫자, 문자열, 배열 등)이 자동으로 결정됩니다. 변수를 선언할 때 타입을 명시할 필요가 없습니다.
  • 예시:
    let number = 10;         // number
    let text = "Hello!";     // string
    let isTrue = true;       // boolean
    
  1. 유연성
  • 같은 변수에 서로 다른 타입의 값을 할당할 수 있습니다(가독성을 위해 권장되지 않음).
  • 예시:
    let data = 10;     // number
    data = "string";   // changed to string
    
  1. 스코프(가시성)
  • 변수의 사용 가능한 범위는 선언 위치에 따라 달라집니다(자세한 내용은 뒤에서 설명).
  1. 재할당 및 재선언
  • 재할당이나 재선언이 가능한지는 사용한 키워드에 따라 다릅니다.
  • 예시:
    var x = 5;
    var x = 10; // redeclaration allowed (not recommended)
    
    let y = 5;
    // let y = 10; // Error (cannot redeclare)
    
    const z = 5;
    // z = 10; // Error (cannot reassign)
    

2.3 변수를 사용할 때의 장점

  1. 재사용성
  • 동일한 값을 여러 번 사용할 필요가 있을 때 변수를 통해 관리하면 편리합니다.
  1. 쉽게 업데이트 가능
  • 변수 값을 한 번 바꾸면 프로그램 전체에 변경 사항이 반영됩니다.
  1. 가독성 및 유지보수성 향상
  • 이름이 붙은 변수를 사용하면 의도가 명확해져 다른 개발자도 코드를 이해하기 쉬워집니다.

2.4 변수를 활용한 간단한 예제

아래는 변수를 이용한 기본 계산 프로그램 예시입니다.

let price = 500;              // item price
let quantity = 3;             // quantity
let total = price * quantity; // calculate total
console.log(`Total is ${total} yen.`);

이 예제에서는 가격과 수량을 변수에 저장하고, 총 금액을 동적으로 계산하여 표시합니다. 변수는 프로그램의 유연성과 효율성을 높이는 방법입니다.

3. 변수 선언 방법 및 키워드 간 차이점

JavaScript에서는 변수를 선언하기 위해 var, let, const 세 가지 키워드를 사용합니다. 각 키워드의 특성을 이해하고 상황에 맞게 선택하면 오류를 방지하고 가독성을 향상시킬 수 있습니다.

3.1 var, let, const의 기본 차이점

1. var – 레거시 선언

var는 JavaScript 초기 버전부터 사용되어 왔습니다.

특징:

  • 재선언 및 재할당이 가능합니다.
  • 함수 스코프를 가집니다(블록 스코프는 무시됩니다).
  • 호이스팅으로 선언이 스코프의 최상단으로 이동합니다.

예시:

var x = 10;
console.log(x); // 10

var x = 20; // redeclaration allowed
console.log(x); // 20

if (true) {
  var y = 30; // ignores block scope
}
console.log(y); // 30

주의사항:

  • 블록 스코프를 무시하기 때문에 의도치 않은 동작을 일으킬 수 있습니다.
  • 현대 JavaScript에서는 사용이 권장되지 않으며, 새로운 코드에서는 피하는 것이 좋습니다.

2. let – 재할당을 위한 권장 선택

let은 ES6(2015)에서 도입되었으며 현재 널리 사용됩니다.

특징:

  • 재선언은 불가능하지만 재할당은 가능합니다.
  • 블록 스코프를 가집니다.
  • 호이스팅은 되지만 초기화 전에 사용하면 Temporal Dead Zone(시간적 사각지대) 오류가 발생합니다.

예시:

let a = 10;
console.log(a); // 10

a = 20; // reassignment allowed
console.log(a); // 20

if (true) {
  let b = 30; // valid only inside this block
  console.log(b); // 30
}
// console.log(b); // Error: b is out of scope

주의사항:

  • 재할당이 필요할 때 let을 사용하고, 재할당이 필요하지 않을 경우 const를 우선 사용하세요.

3. const – 상수를 위한 선언

const도 ES6에서 도입되었으며, 재할당되지 않아야 하는 값을 선언할 때 사용합니다.

특징:

  • 재선언 및 재할당이 불가능합니다.
  • 블록 스코프를 가집니다.
  • 선언과 동시에 초기화해야 합니다.

예시:

const pi = 3.14;
console.log(pi); // 3.14

// pi = 3.1415; // Error: cannot reassign

if (true) {
  const gravity = 9.8;
  console.log(gravity); // 9.8
}
// console.log(gravity); // Error: out of scope

주의사항:

  • 변수 자체는 재할당할 수 없지만, 객체나 배열과 같은 참조 타입인 경우 그 내부 속성·요소는 수정할 수 있습니다.

예시:

const user = { name: "Alice" };
user.name = "Bob"; // property mutation is allowed
console.log(user.name); // Bob

3.2 비교 표: var vs let vs const

Featurevarletconst
RedeclarationAllowedNot allowedNot allowed
ReassignmentAllowedAllowedNot allowed
ScopeFunction scopeBlock scopeBlock scope
HoistingDeclaration + initialization behavior differsDeclaration only (no safe use before init)Declaration only (no safe use before init)
Recommended?Not recommendedRecommendedRecommended

3.3 올바른 선택 방법

  1. 기본적으로 const 사용
  • 재할당이 필요하지 않다면 const를 사용해 안전성을 높이세요.
  1. 재할당이 필요할 때만 let 사용
  • 루프 카운터나 시간이 지남에 따라 변해야 하는 상태 변수 등에 사용하세요.
  1. var는 피하기
  • 레거시 코드에서는 볼 수 있지만, 최신 코드베이스에서는 권장되지 않습니다.

3.4 빠른 사용 요약

const PI = 3.14;           // constant
let count = 0;             // value that changes
for (let i = 0; i < 5; i++) {
  count += i;
}
console.log(count);        // display total
let userName = "Alice";
console.log(userName); // "Alice"
userName = "Bob";
console.log(userName); // "Bob"

4. 변수의 스코프와 수명

JavaScript에서 변수의 스코프(어디서 접근 가능한가)와 수명(메모리에 얼마나 오래 존재하는가)을 이해하는 것은 매우 중요합니다. 이 개념들을 마스터하면 예기치 않은 버그를 방지하고 보다 효율적인 코드를 작성할 수 있습니다.

4.1 스코프란?

Scope는 변수가 접근할 수 있는 범위를 의미합니다. JavaScript에서는 변수가 선언되는 방식에 따라 스코프가 달라집니다.

1. 전역 스코프

전역 스코프는 프로그램 어디서든 접근할 수 있는 스코프를 의미합니다.

예시:

var globalVar = "Global variable";

function showGlobalVar() {
  console.log(globalVar); // Accessible
}

showGlobalVar();
console.log(globalVar); // Accessible

주의:
전역 변수는 어디서든 접근할 수 있기 때문에 이름 충돌 및 의도치 않은 덮어쓰기가 발생하기 쉽습니다. 가능한 최소한으로 유지해야 합니다.

2. 지역 스코프

지역 스코프는 특정 함수나 블록 내부에서만 유효한 스코프를 의미합니다.

예시:

function localExample() {
  let localVar = "Local variable";
  console.log(localVar); // Accessible
}

// console.log(localVar); // Error: out of scope

이 예시에서 변수 localVar는 함수 내부에서만 접근 가능하며, 함수 외부에서는 참조할 수 없습니다.

3. 블록 스코프

letconst로 선언된 변수는 블록({} 로 감싸진 영역) 내부에서만 유효합니다.

예시:

{
  let blockVar = "Block scope";
  console.log(blockVar); // Accessible
}
// console.log(blockVar); // Error: out of scope

중요:
var를 사용해 변수를 선언하면 블록 스코프가 무시되므로 주의가 필요합니다.

{
  var blockVar = "Block scope ignored";
}
console.log(blockVar); // Accessible (not recommended)

4.2 수명(Lifetime)이란?

수명은 변수가 메모리 상에 존재하는 기간을 의미합니다.

  1. 전역 변수의 수명
  • 프로그램이 시작될 때부터 종료될 때까지 존재합니다.
  1. 지역 변수의 수명
  • 함수가 호출될 때부터 함수가 종료될 때까지만 존재합니다.

예시:

function showMessage() {
  let message = "Temporary message";
  console.log(message);
}

showMessage();
// console.log(message); // Error: message is not accessible after the function ends

이 예시에서 함수가 종료되면 변수 message가 소멸되어 더 이상 참조할 수 없습니다.

4.3 스코프 체인(Scope Chain)이란?

중첩된 스코프(예: 중첩 함수)가 형성될 때, JavaScript는 스코프 체인이라는 메커니즘을 사용해 변수를 검색합니다.

예시:

let outerVar = "Outside";

function outerFunction() {
  let innerVar = "Inside";

  function innerFunction() {
    console.log(outerVar); // Accesses outer scope
    console.log(innerVar); // Accesses inner scope
  }

  innerFunction();
}

outerFunction();

이 예시에서 innerFunction은 먼저 자신의 스코프에서 변수를 찾고, 그 다음 부모 스코프, 필요하다면 최종적으로 전역 스코프에서 찾습니다. 이러한 검색 과정이 스코프 체인입니다.

4.4 클로저(Closure) 이해하기

클로저는 내부 함수가 외부 함수의 변수에 계속 접근할 수 있는 기능을 말합니다.

예시:

function createCounter() {
  let count = 0; // Outer variable

  return function () {
    count++; // Accesses outer variable
    return count;
  };
}

const counter = createCounter();
counter(); // 1
counter(); // 2

이 예시에서 내부 함수는 외부 변수 count에 계속 접근하여 상태를 유지합니다. 클로저는 카운터, 설정 관리 등 다양한 용도에 유용합니다.

4.5 스코프와 수명을 효과적으로 활용하기 위한 핵심 포인트

  1. 전역 변수를 최소화하기
  • 이름 충돌 및 의도치 않은 덮어쓰기를 방지하기 위해 전역 변수를 불필요하게 사용하지 않도록 합니다.
  1. 지역 스코프를 적극 활용하기
  • 함수나 블록 내부에서 변수를 관리하면 예상치 못한 버그를 방지할 수 있습니다.
  1. 가능하면 const 사용하기
  • 재할당이 필요하지 않다면 const를 사용해 안전성을 높이세요.
  1. 클로저가 유용한 상황 이해하기
  • 상태 관리나 함수 캡슐화가 필요할 때 클로저를 적극 활용하세요.

5. 변수 초기화와 Undefined 처리

JavaScript에서 변수를 올바르게 초기화하는 것은 중요합니다. 초기화되지 않은 변수와 undefined 값은 예상치 못한 오류를 일으킬 수 있으므로, 그 동작을 이해해야 합니다.

5.1 변수 초기화란?

초기화란 선언 후 변수에 첫 번째 값을 할당하는 것을 의미합니다.

예시:

let count = 0;  // initialized
let message;    // uninitialized

위 예시에서 count는 안전하게 0으로 초기화됩니다. 반면 message는 값이 할당되지 않아 나중에 예상치 못한 동작을 일으킬 수 있습니다.

5.2 undefined 다루기

1. undefined란?

undefined는 다음 경우에 자동으로 할당되는 특수한 값입니다.

  • 초기화되지 않은 변수
  • 존재하지 않는 객체 속성 또는 배열 요소
  • 값을 반환하지 않는 함수

예시:

let value; // uninitialized variable
console.log(value); // undefined

let obj = {};
console.log(obj.property); // undefined (property does not exist)

function noReturn() {}
console.log(noReturn()); // undefined (no return value)

주의사항:

  • undefined는 의도치 않게 발생하는 경우가 많으므로, 코드에서 적절히 처리해야 합니다.

2. undefined 확인 방법

변수나 속성이 undefined인지 안전하게 확인하는 방법을 소개합니다.

예시:

let data;

// Method 1: typeof operator
if (typeof data === "undefined") {
  console.log("The variable is undefined");
}

// Method 2: strict comparison
if (data === undefined) {
  console.log("The variable is undefined");
}

typeof 연산자를 사용하는 것이 더 안전합니다. 변수 자체가 선언되지 않았더라도 오류가 발생하지 않기 때문입니다.

5.3 null 다루기

1. null이란?

null은 “의도적으로 비어 있음”을 나타내는 값입니다. undefined와 달리 개발자가 직접 설정합니다.

예시:

let value = null;
console.log(value); // null

2. undefinednull의 차이점

Featureundefinednull
MeaningNot defined (automatically set by the system)Intentionally empty (set by the developer)
Typeundefinedobject (a historical design mistake, but still the spec)
Comparisonundefined == null is trueStrict comparison undefined === null is false

예시:

console.log(undefined == null);  // true
console.log(undefined === null); // false

주의사항:

  • null은 “빈 값”임을 명시적으로 나타낼 때 사용합니다.
  • undefined와 구분함으로써 코드 의도를 명확히 할 수 있습니다.

5.4 초기화 모범 사례

1. 항상 초기화하기

선언 시 값을 할당해 undefined 상태를 방지합니다.

예시:

let count = 0;     // initialized
let message = "";  // initialized with an empty string

2. null을 사용해 의도 명시하기

데이터가 아직 결정되지 않은 경우, 나중에 값을 설정할 것임을 나타내기 위해 null로 초기화합니다.

예시:

let result = null; // will be assigned later

3. 값이 초기화되었는지 확인하기

함수 인자나 반환값이 undefined인지 확인합니다.

예시:

function greet(name) {
  if (name === undefined || name === null) {
    console.log("No name provided");
  } else {
    console.log(`Hello, ${name}!`);
  }
}

greet();        // No name provided
greet("Taro");  // Hello, Taro!

5.5 흔한 오류와 해결 방법

1. ReferenceError

원인: 선언되지 않은 변수를 접근했을 때 발생합니다.
예시:

console.log(name); // Error: name is not defined

해결:
사용하기 전에 변수를 선언하고 초기화합니다.

2. TypeError

원인: null 또는 undefined인 값의 속성에 접근하려 할 때 발생합니다.
예시:

let obj = null;
console.log(obj.property); // Error: cannot read properties

해결:
사전에 값이 유효한지 확인합니다.

if (obj !== null && obj !== undefined) {
  console.log(obj.property);
}

5.6 요약

변수 초기화와 undefined 값 처리는 JavaScript의 기본적인 기술입니다. 변수를 올바르게 초기화하고 안전하게 검사함으로써 예상치 못한 오류를 예방할 수 있습니다.

6. 변수 명명 규칙 및 모범 사례

In JavaScript에서 변수 이름을 짓는 방식은 코드 가독성과 유지보수성에 큰 영향을 미칩니다. 올바른 네이밍 규칙을 따르면 코드의 의도가 명확해지고 오류를 피하기가 쉬워집니다. 이 섹션에서는 변수 네이밍 규칙과 모범 사례를 자세히 설명합니다.

6.1 변수 이름에 대한 기본 규칙

JavaScript에서 변수 이름은 다음 규칙을 따라야 합니다.

1. 허용되는 문자

  • 알파벳 문자 (a–z, A–Z)
  • 숫자 (0–9)
  • 언더스코어 (_)
  • 달러 기호 ($)

2. 허용되지 않는 패턴

  • 변수 이름은 숫자로 시작할 수 없습니다. 예시:
    let 1name = "Error"; // Error
    let name1 = "Correct";
    
  • JavaScript 예약어는 사용할 수 없습니다(예: let, const, class). 예시:
    let const = "Error"; // Error
    let value = "Correct";
    
  • 공백 및 특수 문자는 허용되지 않습니다. 예시:
    let user name = "Error"; // Error
    let userName = "Correct";
    

6.2 일반적인 네이밍 스타일

JavaScript에서 흔히 사용되는 네이밍 스타일이 몇 가지 있습니다.

1. camelCase (권장)

첫 번째 단어는 소문자로 시작하고, 이후 단어는 대문자로 시작합니다.

예시:

let userName = "Taro";      // Recommended
let totalAmount = 500;     // Recommended

2. snake_case (제한적 사용)

단어를 언더스코어(_)로 구분합니다. 이 스타일은 주로 상수나 데이터베이스 관련 코드에서 사용됩니다.

예시:

let user_name = "Taro"; // Allowed but not common in JavaScript

3. PascalCase (클래스 및 생성자용)

각 단어의 첫 글자를 대문자로 씁니다. 클래스 이름이나 생성자 함수에 일반적으로 사용됩니다.

예시:

class UserProfile {
  constructor(name) {
    this.name = name;
  }
}

4. UPPER_SNAKE_CASE (상수용)

상수는 보통 대문자와 언더스코어 조합으로 표기합니다.

예시:

const MAX_VALUE = 100;
const DEFAULT_TIMEOUT = 5000;

6.3 모범 사례

1. 의미 있는 이름 사용

변수 이름은 그 목적을 명확히 설명해야 합니다.

잘못된 예시:

let x = 10; // Meaning unclear

올바른 예시:

let itemCount = 10; // Clearly represents the number of items

2. 과도한 축약 피하기

과도한 축약은 가독성을 떨어뜨립니다.

잘못된 예시:

let nm = "Taro"; // Unclear

올바른 예시:

let userName = "Taro"; // Clear intent

3. 일관성 유지

코드 전체에서 동일한 네이밍 규칙을 사용합니다.

잘못된 예시:

let user_name = "Taro"; // snake_case
let userAge = 25;       // camelCase (inconsistent)

올바른 예시:

let userName = "Taro";
let userAge = 25; // Consistent camelCase

4. Boolean 플래그는 논리적인 이름 사용

Boolean 변수는 조건이나 상태를 설명해야 합니다.

잘못된 예시:

let flag = true; // Ambiguous

올바른 예시:

let isLoggedIn = true; // Clearly represents state

5. 숫자와 단위 명시

변수가 숫자값이나 단위를 나타낼 경우 이를 명시합니다.

잘못된 예시:

let size = 10; // Unit unclear

올바른 예시:

let fontSizePx = 10; // Font size in pixels

6.4 네이밍 가이드라인 및 주의사항

  1. 영어 사용 프로그래밍은 표준 언어로 영어를 사용합니다. 일본어 혹은 로마자 변수명을 피하세요.

잘못된 예시:

let namae = "Taro"; // Avoid romanized Japanese

올바른 예시:

let userName = "Taro"; // Use English
  1. 필요할 경우 접두사·접미사 사용 접두사나 접미사를 추가하면 변수의 역할을 명확히 할 수 있습니다.

예시:

let btnSubmit = document.getElementById("submit"); // Button element
let arrUsers = ["Taro", "Hanako"];                 // Array

7. 흔히 발생하는 오류와 해결 방법

JavaScript에서는 변수 선언 및 사용과 관련된 오류가 자주 발생합니다. 이러한 오류는 코드 실행을 중단시키거나 의도하지 않은 동작을 일으킬 수 있습니다. 이 섹션에서는 흔히 발생하는 오류와 그 처리 방법을 설명합니다.

7.1 ReferenceError

원인

ReferenceError는 존재하지 않거나 스코프 밖에 있는 변수를 접근하려 할 때 발생합니다.

예시: 선언되지 않은 변수에 접근하기

console.log(value); // Error: value is not defined

해결 방법

  1. 변수를 사용하기 전에 선언합니다.
    let value = 10;
    console.log(value); // 10
    
  1. 변수의 스코프를 확인합니다.
    function test() {
      let localVar = "Local variable";
    }
    // console.log(localVar); // Error: out of scope
    

7.2 TypeError

원인

TypeError는 값이 기대한 타입이 아닐 때 발생합니다.

예시: undefined의 속성에 접근하기

let obj;
console.log(obj.property); // Error: Cannot read properties of undefined

해결 방법

  1. 초기화와 데이터 타입을 미리 확인합니다.
    let obj = {};
    console.log(obj.property); // undefined (no error)
    
  1. 옵셔널 체이닝 연산자(?.)를 사용합니다.
    let obj;
    console.log(obj?.property); // undefined (no error)
    

7.3 SyntaxError

원인

SyntaxError는 코드에 문법적인 실수가 있을 때 발생합니다.

예시: 세미콜론 누락

let x = 10
let y = 20;

해결 방법

  1. 코드 편집기나 린팅 도구(예: ESLint)를 사용해 문법 오류를 감지합니다.
  2. 코드를 실행하고 브라우저 개발자 도구 또는 Node.js에서 오류 메시지를 확인합니다.

7.4 Uncaught Error

원인

Uncaught Errortry...catch로 처리되지 않은 예외가 발생했을 때 나타납니다.

예시:

throw new Error("Something went wrong!");

해결 방법

  1. 예외 처리를 추가합니다.
    try {
      throw new Error("Error occurred!");
    } catch (error) {
      console.log(error.message); // Error occurred!
    }
    
  1. 오류 메시지를 적절히 로그에 남겨 디버깅을 용이하게 합니다.

7.5 RangeError

원인

RangeError는 값이 허용 범위를 벗어났을 때 발생합니다.

예시 1: 배열 인덱스가 범위를 초과함

let arr = [1, 2, 3];
console.log(arr[5]); // undefined (not an error, but unintended)

예시 2: 잘못된 배열 길이

new Array(-1); // Error: Invalid array length

해결 방법

  1. 배열에 접근하기 전에 인덱스를 확인합니다.
    let arr = [1, 2, 3];
    if (arr[5] !== undefined) {
      console.log(arr[5]);
    } else {
      console.log("Out of range");
    }
    
  1. 반복문 조건과 배열 길이를 적절히 제어합니다.

7.6 기타 흔한 오류

1. NaN

원인: 숫자 연산 결과가 숫자가 아닌 경우 발생합니다.
예시:

let result = parseInt("abc"); // NaN

해결 방법

  • isNaN()을 사용해 확인합니다.
    if (isNaN(result)) {
      console.log("Invalid number");
    }
    

2. Infinity

원인: 0으로 나누거나 매우 큰 계산을 수행할 때 발생합니다.
예시:

let value = 1 / 0; // Infinity

해결 방법

  • 계산을 수행하기 전에 값을 검증합니다.
    let value = 10;
    if (value !== 0) {
      console.log(100 / value);
    } else {
      console.log("Cannot divide by zero");
    }
    

7.7 요약

오류는 JavaScript 개발에서 피할 수 없는 요소이지만, 오류의 원인을 이해하고 적절한 처리 기법을 적용하면 프로그램을 안정적으로 유지할 수 있습니다. 오류가 발생하기 쉬운 영역을 미리 파악하고 적절한 오류 처리를 구현하는 것이 신뢰할 수 있는 코드를 작성하는 데 필수적입니다.

8. 실전 예제: JavaScript 변수를 활용한 프로그램

이 섹션에서는 JavaScript 변수에 대해 배운 내용을 실제 프로그램 예제로 적용합니다. 간단한 사례부터 약간 더 복잡한 사례까지 단계별로 직접 구현해 보겠습니다.

8.1 예제 1: 계산 애플리케이션

문제:

Create a program that stores a product’s price and quantity in variables, then calculates and displays the total cost.

코드 예시:

const pricePerItem = 500;        // price per item (constant)
let quantity = 3;               // quantity (variable)
let totalPrice = pricePerItem * quantity; // calculate total

console.log(`The total price is ${totalPrice} yen.`);

설명:

  1. 상수 pricePerItem은 변하지 않는 아이템 가격을 나타냅니다.
  2. 변수 quantity는 아이템 수를 저장하며 업데이트할 수 있습니다.
  3. 계산 결과는 totalPrice에 저장되고 템플릿 리터럴을 사용하여 표시됩니다.

8.2 예제 2: 조건 논리를 이용한 할인 계산

문제:

총 구매 금액에 따라 할인을 적용하는 프로그램을 만드세요.

코드 예시:

let totalAmount = 1200; // total purchase amount
let discount = 0;       // discount rate (initialized)

if (totalAmount >= 1000) {
  discount = 0.1; // 10% discount
} else if (totalAmount >= 500) {
  discount = 0.05; // 5% discount
}

let discountedAmount = totalAmount - totalAmount * discount;
console.log(`The discounted price is ${discountedAmount} yen.`);

설명:

  1. discount를 초기화하면 조건이 일치하지 않아도 오류를 방지할 수 있습니다.
  2. 할인율은 조건문을 사용하여 결정됩니다.
  3. 변수를 사용하면 조건이나 값을 쉽게 수정할 수 있습니다.

8.3 예제 3: 배열과 루프를 이용한 데이터 관리

문제:

배열을 사용하여 제품 및 가격 목록을 관리하고, 총 비용을 계산하세요.

코드 예시:

const items = ["Apple", "Banana", "Orange"]; // item names
const prices = [100, 200, 150];              // prices
let totalCost = 0;                           // total cost

for (let i = 0; i < items.length; i++) {
  console.log(`${items[i]}: ${prices[i]} yen`);
  totalCost += prices[i];
}

console.log(`Total cost: ${totalCost} yen`);

설명:

  1. 배열을 사용하면 여러 관련 데이터를 효율적으로 관리할 수 있습니다.
  2. 루프를 사용하면 코드를 중복하지 않고 각 항목을 처리합니다.
  3. 변수 totalCost는 합계를 누적합니다.

8.4 예제 4: 함수로 재사용 가능한 계산

문제:

세금을 계산하는 재사용 가능한 함수를 만드세요.

코드 예시:

function calculateTax(price, taxRate = 0.1) {
  return price + price * taxRate;
}

let itemPrice = 1000;                 // item price
let finalPrice = calculateTax(itemPrice); // price including tax
console.log(`Price with tax: ${finalPrice} yen`);

설명:

  1. calculateTax 함수는 세금이 포함된 가격을 반환합니다.
  2. 기본 매개변수를 사용하면 세율을 지정하지 않아도 함수가 동작합니다.
  3. 재사용 가능한 함수는 유지보수성과 효율성을 향상시킵니다.

8.5 예제 5: 사용자 입력 처리

문제:

사용자에게 이름과 나이를 물어보고, 성인인지 여부를 판단하는 프로그램을 만드세요.

코드 예시:

let userName = prompt("Please enter your name:");
let age = parseInt(prompt("Please enter your age:"), 10);

if (age >= 18) {
  console.log(`${userName} is an adult.`);
} else {
  console.log(`${userName} is a minor.`);
}

설명:

  1. prompt는 사용자 입력을 수집하는 데 사용됩니다.
  2. parseInt는 문자열 입력을 숫자로 변환합니다.
  3. 명확한 변수 이름은 코드를 이해하기 쉽게 만듭니다.

8.6 요약

이 섹션에서는 JavaScript 변수를 활용한 실용적인 예제를 살펴보았습니다.

핵심 정리:

  1. 계산 앱: 기본 산술 연산 및 변수 관리를 구현합니다.
  2. 조건부 할인: 조건에 따라 값을 동적으로 변경합니다.
  3. 배열과 루프: 여러 데이터 포인트를 효율적으로 관리하고 처리합니다.
  4. 함수: 재사용성과 유지보수성을 향상시킵니다.
  5. 사용자 입력: 변수를 사용해 인터랙티브한 프로그램을 구축합니다.

9. FAQ (자주 묻는 질문)

이 섹션은 JavaScript 변수에 대한 일반적인 질문에 답변하며, 초보자 실수와 보다 고급적인 고민까지 다룹니다.

Q1: var, let, const 중 어느 것을 사용해야 할까요?

A:

대부분의 경우 기본값으로 const 를 사용하세요.

  • 재할당과 재선언을 방지하여 코드가 더 안전해집니다.
  • 값이 변하지 않아야 함을 명확히 표현합니다.

재할당이 필요할 때만 let 을 사용하세요.

현대 JavaScript에서는 var 를 피하십시오. 블록 스코프를 무시하고 예기치 않은 버그를 일으킬 수 있습니다.

Q2: JavaScript에서 변수 타입을 선언해야 하나요?

A:

아니요. JavaScript는 동적 타입 언어이므로 변수 타입은 할당된 값에 따라 자동으로 결정됩니다.

예시:

let value = 10;     // number
value = "string";  // string (no error)

하지만 동적 타이핑은 의도치 않은 버그를 초래할 수 있으니 주의가 필요합니다. TypeScript를 사용하면 타입 안전성을 높일 수 있습니다.

Q3: const 로 선언한 객체의 프로퍼티를 수정할 수 있나요?

A:

예. const 는 변수 자체의 재할당을 방지하지만, 객체의 프로퍼티는 여전히 수정할 수 있습니다.

예시:

const user = { name: "Alice" };
user.name = "Bob"; // property update allowed
console.log(user);

// user = {}; // Error: reassignment not allowed

Q4: undefined와 null의 차이는 무엇인가요?

A:

  • undefined: 변수가 선언은 되었지만 값이 할당되지 않은 상태.
  • null: 명시적으로 “빈” 값이 할당된 상태.

예시:

let a;        // undefined
let b = null; // explicitly empty

Q5: 전역 변수를 피해야 하는 이유는?

A:

전역 변수는 여러 문제를 일으킬 수 있습니다:

  1. 이름 충돌: 충돌 가능성이 높아집니다.
  2. 유지보수성 저하: 값이 어디서 변경되는지 추적하기 어려워집니다.
  3. 디버깅 어려움: 값이 예기치 않게 덮어써질 수 있습니다.

해결책:
필요한 경우 전역 변수를 네임스페이스 객체에 모아 관리하세요.

예시:

const App = {
  userName: "Alice",
  userAge: 25
};

console.log(App.userName);

Q6: 어떤 네이밍 컨벤션을 사용해야 할까요?

A:

권장되는 컨벤션은 다음과 같습니다:

  1. camelCase: 변수와 함수에 사용합니다.
    let userName = "Alice";
    
  1. PascalCase: 클래스와 생성자에 사용합니다.
    class UserProfile {}
    
  1. UPPER_SNAKE_CASE: 상수에 사용합니다.
    const MAX_COUNT = 100;
    

Q7: 클로저란 무엇인가요?

A:

클로저는 함수가 외부 스코프의 변수에 대한 접근 권한을 유지하는 기능을 말합니다.

예시:

function counter() {
  let count = 0;

  return function () {
    count++;
    return count;
  };
}

const increment = counter();
console.log(increment()); // 1
console.log(increment()); // 2

클로저는 상태 관리와 캡슐화에 유용합니다.

10. 결론

이 글에서는 JavaScript 변수에 대해 기본 개념부터 고급 사용법까지 포괄적으로 다루었습니다. 변수는 데이터를 관리하고 유연하며 효율적인 프로그램을 작성하는 데 필수적인 요소입니다.

10.1 핵심 포인트 요약

1. 변수 기본

  • 변수는 데이터를 일시적으로 저장해 재사용할 수 있게 합니다.
  • 동적 타이핑은 유연성을 제공하지만 신중한 관리가 필요합니다.

2. 선언 방법

  • var: 함수 스코프, 재선언 가능하지만 권장되지 않음.
  • let: 블록 스코프, 재할당 가능.
  • const: 블록 스코프, 대부분의 경우 가장 안전한 선택.

3. 스코프와 생명주기

  • 스코프는 변수가 접근 가능한 범위를 정의합니다.
  • 전역 변수를 최소화하고 지역/블록 스코프를 활용하세요.

4. 초기화와 undefined 처리

  • undefined: 값이 설정되지 않았을 때 자동으로 할당됩니다.
  • null: 명시적으로 빈 값을 나타냅니다.

5. 네이밍 및 모범 사례

  • 의미 있고 일관된 이름 사용 (camelCase 권장).
  • 상수는 UPPER_SNAKE_CASE 사용.

6. 흔히 발생하는 오류

  • 흔한 오류(ReferenceError, TypeError 등)를 이해하면 디버깅 효율이 향상됩니다.
  • 적절한 오류 처리는 프로그램 안정성을 높입니다.

7. 실용적인 코드 예시

  • 직접 해보는 예제에서는 계산, 조건문, 배열, 함수, 사용자 입력을 다룹니다.

10.2 다음 단계

1. 고급 주제로 이동하기

  • 함수와 메서드: 모듈화와 재사용성을 향상시킵니다.
  • 객체와 클래스: 복잡한 데이터 구조를 다룹니다.
  • 현대 ES6+ 기능: 템플릿 리터럴, 화살표 함수, 구조 분해 할당 등.

2. 실제 프로젝트로 연습하기

실제 프로젝트에 변수를 적용하면 이해도가 깊어집니다.

예시:

  • 간단한 ToDo 앱 만들기.
  • 계산기 또는 캘린더 도구 만들기.
  • 폼 검증 구현하기.

10.3 마무리 생각

JavaScript 변수는 프로그래밍의 핵심 구성 요소입니다. 변수를 올바르게 선언하고 관리하면 안전하고 효율적이며 유지 보수가 쉬운 코드를 작성할 수 있습니다.

이 글에서 얻은 체계적인 지식—기초부터 고급 사용까지—을 바탕으로 실습을 지속하고 JavaScript 실력을 다지는 데 충분히 준비되었습니다.

広告