Variable
변수
프로그램에서 데이터를 저장하는 메모리 공간에 붙이는 이름. let, const, var의 차이와 스코프를 이해하면 안정적이고 예측 가능한 코드를 작성할 수 있습니다.
변수
프로그램에서 데이터를 저장하는 메모리 공간에 붙이는 이름. let, const, var의 차이와 스코프를 이해하면 안정적이고 예측 가능한 코드를 작성할 수 있습니다.
변수(Variable)는 프로그램에서 데이터를 저장하고 참조하기 위한 메모리 공간에 붙이는 이름입니다. "변할 수 있는 값"이라는 의미로, 프로그램 실행 중에 값이 변경될 수 있습니다. 예를 들어 let count = 0;이라고 선언하면, 메모리 어딘가에 0이라는 값이 저장되고, 우리는 "count"라는 이름으로 그 값에 접근하고 변경할 수 있습니다. 변수는 프로그래밍의 가장 기본적인 개념이며, 모든 언어에서 필수적으로 사용됩니다.
스코프(Scope)는 변수가 접근 가능한 범위를 의미합니다. 전역 스코프(Global Scope)의 변수는 프로그램 어디서든 접근 가능하고, 지역 스코프(Local Scope)의 변수는 선언된 함수 내부에서만 접근 가능합니다. ES6부터 도입된 블록 스코프(Block Scope)는 { } 중괄호 내부에서만 유효합니다. JavaScript의 let과 const는 블록 스코프를 따르지만, var는 함수 스코프를 따라서 의도치 않은 버그가 발생할 수 있습니다.
JavaScript에서 let, const, var의 차이는 매우 중요합니다. var는 ES6 이전의 변수 선언 방식으로, 함수 스코프를 가지며 호이스팅(Hoisting) 시 undefined로 초기화됩니다. let은 블록 스코프를 가지며, 호이스팅되지만 초기화 전에 접근하면 TDZ(Temporal Dead Zone) 에러가 발생합니다. const는 let과 동일한 스코프 규칙을 따르지만, 선언 시 반드시 초기화해야 하고 재할당이 불가능합니다. 단, 객체나 배열의 내부 값은 변경할 수 있습니다.
네이밍 컨벤션(Naming Convention)은 코드의 가독성과 유지보수성에 직접적인 영향을 미칩니다. JavaScript에서는 camelCase를 사용하고, Python에서는 snake_case를 사용합니다. 변수 이름은 그 역할을 명확히 나타내야 합니다. d보다 elapsedTimeInDays가, temp보다 currentTemperature가 좋습니다. 약어는 피하고, 불린 변수는 isActive, hasPermission처럼 is/has/can으로 시작하면 의미가 명확해집니다.
// 1. var - 함수 스코프, 호이스팅 시 undefined로 초기화 console.log(varVariable); // undefined (에러 아님!) var varVariable = "var로 선언"; // 2. let - 블록 스코프, TDZ 존재 // console.log(letVariable); // ReferenceError: TDZ let letVariable = "let으로 선언"; // 3. const - 재할당 불가, 객체 내부는 변경 가능 const PI = 3.14159; // PI = 3.14; // TypeError: 재할당 불가 const user = { name: "김개발", age: 25 }; user.age = 26; // 객체 내부 변경은 가능! console.log(user); // { name: "김개발", age: 26 } // 4. 스코프 비교 function scopeExample() { if (true) { var functionScoped = "var: 함수 스코프"; let blockScoped = "let: 블록 스코프"; } console.log(functionScoped); // "var: 함수 스코프" // console.log(blockScoped); // ReferenceError } // 5. for 루프에서의 차이 (클로저 문제) for (var i = 0; i < 3; i++) { setTimeout(() => console.log("var:", i), 100); } // 출력: 3, 3, 3 (의도치 않은 결과!) for (let j = 0; j < 3; j++) { setTimeout(() => console.log("let:", j), 100); } // 출력: 0, 1, 2 (의도한 결과)
// 1. 전역 변수 (가능하면 피하기) let globalCount = 0; // 어디서든 접근 가능 - 위험! // 2. 지역 변수와 스코프 체인 const outerValue = "외부"; function outer() { const middleValue = "중간"; function inner() { const innerValue = "내부"; // 스코프 체인: inner -> outer -> global console.log(innerValue); // "내부" (자신의 스코프) console.log(middleValue); // "중간" (외부 스코프) console.log(outerValue); // "외부" (전역 스코프) } inner(); } // 3. 클로저를 활용한 private 변수 function createCounter() { let count = 0; // private 변수 (외부에서 직접 접근 불가) return { increment() { count += 1; return count; }, decrement() { count -= 1; return count; }, getCount() { return count; } }; } const counter = createCounter(); console.log(counter.increment()); // 1 console.log(counter.increment()); // 2 console.log(counter.getCount()); // 2 // counter.count; // undefined (직접 접근 불가)
let d = new Date() - startTime;이라고 되어있는데, d가 뭘 의미하는지 바로 알기 어렵네요. 변수 이름을 좀 더 명확하게 바꿔주실 수 있을까요?
const elapsedTimeMs = Date.now() - startTime;으로 바꾸면 될까요? const로 바꾼 이유는 이 값을 나중에 변경하지 않아서요.
let flag = true;는 isProcessing이나 shouldContinue처럼 의미를 담은 이름이 좋겠어요.
undefined로 초기화되어서, 선언 전에 접근해도 에러 없이 undefined가 나옵니다. 반면 let과 const는 호이스팅되지만 초기화되지 않아서, 선언 전에 접근하면 TDZ(Temporal Dead Zone) 에러가 발생합니다. 이런 차이 때문에 let/const가 더 안전하고, 요즘은 var 대신 let/const를 사용합니다.
no-var 규칙을 활성화하세요.temp, data, result 같은 모호한 이름 대신 userProfile, filteredProducts처럼 구체적인 이름을 사용하세요.