[JavaScript] What - var, let, const

하쮸·2025년 9월 20일

Error, Why, What, How

목록 보기
32/62

1. var


1-1. 지역 변수.

  • 지역 변수를 선언하려면 예약어 var과 함께 변수를 선언해야됨.
    • 지역 변수(local variable)는 함수 안에서 선언하고 함수 안에서만 사용 가능.
<script>		
  function addNumber() { 								
  var sum = 10 + 20;      // 지역 변수 선언
}
addNumber();
console.log(sum);         // 지역 변수 sum 출력.
</script>
  • 지역 변수 sum을 addNumber() 함수 안에서 선언하였는데 함수 바깥에서 console.log()로 출력하려고 해서 에러가 발생.

1-2. 전역 변수.

  • 전역 변수로 선언하려면 함수 바깥에서 선언하거나 함수 안에서 var를 사용하지 않고 선언하면 됨.
    • 전역 변수는 지역 변수와는 다르게 스크립트 소스 코드 전체에서 사용 가능.
<script>
  var num = 10;
function addNumber() { 								
  var sum = 10 + 20;	  // 지역 변수
  multi = 10 * 20;        // 전역 변수 
}
addNumber();
console.log(multi);
console.log(num);
</script>


1-3. 재선언, 재할당.

  • var를 사용한 변수재선언, 재할당을 할 수 있음.
<script>		
  function addNumber(num1, num2) { 								
  return num1 + num2;						
}
var sum = addNumber(10, 20);    // 선언
console.log("sum = ", sum);
sum = 50;						// 재할당
console.log("sum = ", sum);
var sum = addNumber(20, 20);	// 재선언
console.log("sum = ", sum);
sum = 100;						// 재할당
console.log("sum = ", sum);
</script>

  • 함수의 반환값을 저장했다는 것을 까먹고 새로운 sum 변수를 선언하더라도 에러가 발생하지않음.
    • 이럴 경우 예상치 못한 결과가 발생할 수 있으므로 조심해서 사용해야함.

1-4. 호이스팅 (hoisting)

  • 호이스팅 (hoisting)이란?
    • hoisting = 끌어올린다
      상황에 따라 변수의 선언과 할당분리해서 선언 부분을 스코프의 최상단으로 끌어올려서 소스를 해석함.
// ↓ 원본 코드
<script>		 
  var x = 1;

function displayNumber() {
  console.log("x = " + x);
  console.log("y = " + y);      
  var y = 2;
}
displayNumber();
</script>

// ↓ 자바스크립트 인터프리터가 해석한 코드
<script>		 
  var x = 1;

function displayNumber() {
  var y    // (호이스팅(hoisting))
  console.log("x = " + x);
  console.log("y = " + y);      
  y = 2;
}
displayNumber();
</script>

  • 호이스팅때문에 위와 같은 결과가 나타남.
    • 자바스크립트 인터프리터는 함수 코드를 훑어보면서 var 변수를 따로 저장해둠.
  • 이처럼 var 변수선언하기 전에 사용할 경우 프로그램에서 에러가 발생할 수 있음.

2. ES6 업데이트.

  • var를 자칫 잘못 사용하면 예상치 못한 결과가 발생하게 되어 프로그램에서 에러가 발생할 수 있음.

  • ES6부터는 var 사용을 지양하고 let, const 사용을 지향함.

    • var함수 영역의 스코프를 가짐.
      let, const블록 영역의 스코프를 가짐.

2-1. let

  • let 변수는 변수를 선언한 블록({})에서만 유효하고 블록을 벗어나면 사용할 수 없음.
<script>
  function calcSum(n) {
  let sum = 0;      
  for(let i = 1; i < n + 1; i++) {						
    sum += i;	
  }      
  console.log(sum);
}
calcSum(10);

console.log(sum);   // Uncaught ReferenceError: sum is not defined  
</script>
  • 위 코드에서
    let sum을 사용할 수 있는 범위는 calcSum() 함수 내부에서만 사용할 수 있음.
    let i를 사용할 수 있는 범위는 for() 반복문 내부에서만 사용할 수 있음.

2-1-1. 전역 변수.

  • 만약 전역 변수로 선언하고 싶다면 변수 이름과 초깃값만 할당하면 됨.
<script>
  function calcSum(n) {
  	sum = 0;        // 전역 변수.
  	for(let i = 1; i < n + 1; i++) {						
    	sum += i;	
  	}            
  }    
calcSum(10);    
console.log(sum);
</script>

2-1-2. 재할당 (O), 재선언 (X)

  • let 변수는 값을 재할당할 수는 있지만 재선언할 수는 없음.

재할당

  <script>
    function calcSum(n) {
      let sum = 0;
      for(let i = 1; i < n + 1; i++) {						
        sum += i;	
      }
      console.log("첫 번째 sum : " + sum);
      sum = 100;
      console.log("두 번째 sum(값 재할당) : " + sum);
    }    
    calcSum(10);    
  </script>

재선언

  <script>
    function calcSum(n) {
      let sum = 0;
      for(let i = 1; i< n + 1; i++) {						
        sum += i;	
      }
      console.log("첫 번째 sum : " + sum);    // 콘솔창 출력자체가 안됨.

      let sum;    // Uncaught SyntaxError: Identifier 'sum' has already been declared
      console.log("두 번째 sum(변수 재선언) : " + sum);
    }    
    calcSum(10);    
  </script>

  • 따라서 let 예약어를 사용하면 같은 변수 이름을 중복해서 사용할 수 없음.

2-1-3. 호이스팅 없음.

  • var 변수의 경우 변수를 선언하기 전에 해당 변수를 사용해서 실행하더라도 아직 할당되지 않는 자료형인 undefined 값을 가질 수 있음.
    • 호이스팅 때문에 가능.
  • let 변수의 경우 변수를 선언하기 전에 해당 변수를 사용할 경우 에러가 발생함.
  <script>		 
    var x = 10;

		function displayNumber() { 								
      console.log("x is " + x);
      console.log("y is " + y);   // 변수 선언보다 먼저 사용. (Uncaught ReferenceError: Cannot access 'y' before initialization)   
      let y = 20;
		}
    displayNumber();
  </script>


2-2. const

  • const로 선언한 변수는 상수(constant)임.
    • 즉, 변하지 않는 값을 변수로 선언할 때 const를 사용함.
  • 재선언, 재할당 할 수 없음.
  • let과 마찬가지로 블록 레벨스코프를 가짐.

재선언

  <script>
    const currentYear = 2020;   
    console.log(currentYear);
    // const currentYear;          // Uncaught SyntaxError: Identifier 'currentYear' has already been declared.
    console.log(currentYear);
  </script>

재할당

  <script>
    const currentYear = 2020;
    console.log(currentYear);
    currentYear = 2100;         // Uncaught TypeError: Assignment to constant variable.
    console.log(currentYear);
  </script>


3. 결론.

  • 변수로 인해 발생하는 에러를 줄이려면 let, const를 사용하는 것이 좋음.
    • 값이 자주 바뀌는 변수라면 let을 사용. 재할당이 없는 변수라면 const를 사용.
  • 자바스크립트는 유연해서 편리한 언어이지만 이로인해 소스코드가 많아질수록 가독성이나 디버깅을 하기 어려움.

  • 전역 변수최소한으로 사용.
    • 전역 변수는 어디서든 접근할 수 있으므로 편리하지만 예상하지 못한 곳에서 값이 달라질 수도 있음.
      그만큼 오류가 발생할 확률이 높아지므로 전역 변수는 되도록 적게 사용하는 게 좋음.
  • var 변수함수 시작 부분에서 선언.
    • var 변수는 내부에서 호이스팅이 생기므로 오류가 발생할 수 있음.
      따라서 함수 시작 부분에 선언하는 것이 변수를 확인하기도 쉽고 에러를 줄이는 방법임.
  • for 문에서 카운터 변수를 사용할 때는 var를 사용하지 않음.
    • var 변수함수 레벨의 스코프임.
    • for 문의 카운터 변수는
      for 문 바깥에서 var 변수로 선언하거나
      let 변수를 사용해서 블록 변수로 선언하는 것이 좋음.
var i;
for (i = 1; i <= n; i++) {
  	...
}
    
for (let i = 1; i <= n; i++) {
  	...
}
  • ES6에서는 var 보단 let을 사용하는 게 좋음.
    • var를 사용해서 선언한 변수는 재선언할 수 있으므로 실수로 같은 변수를 다시 선언하더라도 에러가 발생하지 않음.
      그래서 재선언할 수 없는 let을 사용하는 것이 좀 더 안전함.
profile
Every cloud has a silver lining.

0개의 댓글