JavaScript/JavaScript 문법

[JavaScript]변수 선언과 호이스팅(Hoisting)

DevStory 2021. 8. 17.

JavaScript변수 선언 방법호이스팅(Hoisting) 개념에 대해 정리합니다.

 

변수 선언 방법호이스팅은 간단한 개념이지만, 이번 기회에 정확하게 정리하고자 합니다.

 


변수 선언 방법

JavaScript에서는 변수를 var 키워드를 이용하여 선언할 수 있습니다.

(letconst 키워드는 추후 정리할 예정입니다.)

 

변수마다 var 키워드를 사용하여 변수를 선언할 수 있습니다.

var value;
var name;

 

콤마( , )를 사용하여 한 줄로 선언할 수도 있습니다.

var value, name;

 

그리고 변수 선언과 동시에 초기화를 할 수도 있습니다.

var languane = 'Korean';
var a = 0, b = 1, c = 2;

 

변수에 초기 값을 설정하지 않는다면, 변수의 값은 undefined입니다.

변수의 값이 설정되면, 설정된 값으로 적용됩니다.

var language;
console.log(language);
// undefined

language = 'Korean';
console.log(language);
// Korean

 

JavaScript는 다른 프로그래밍 언어에 비해 타입이 자유롭기 때문에 변수에 숫자로 값을 설정했다가 문자열로 변경가능합니다.

typeof 연산자를 사용하여 변경된 변수의 타입을 확인할 수 있습니다.

var num = 100;
console.log(num);
// 100
console.log(typeof num);
// number

num = "백이다";
console.log(num);
// 백이다
console.log(typeof num);
// string

전역 변수와 함수 내부의 지역 변수 이름이 동일

함수 내부에서 전역 변수와 동일한 이름의 변수를 선언할 경우 지역 변수를 우선으로 합니다.

var num = 10;

function funcNum() {
  var num = '지역 변수의 num';
  // funcNum 함수 내부의 지역 변수 num을 반환합니다.
  return num;
}

console.log(funcNum());
// 지역 변수의 num

console.log(num);
// 10

 

함수 내부에서 var 키워드를 사용하지 않는다면, 함수 내부에서 전역 변수의 값을 변경합니다.

var num = 10;

function funcNum() {
  // funcNum 함수 내부에서 전역 변수 num의 값을 변경합니다.
  num = '지역 변수의 num';
  return num;
}

console.log(funcNum());
// 지역 변수의 num

console.log(num);
// 지역 변수의 num

 

var 키워드를 제거하고 전역 변수를 선언해도 결과는 똑같습니다.

num = 10;

function funcNum() {
  // funcNum 함수 내부에서 전역 변수 num의 값을 변경합니다.
  num = '지역 변수의 num';
  return num;
}

console.log(funcNum());
// 지역 변수의 num

console.log(num);
// 지역 변수의 num

호이스팅(Hoisting)

다른 프로그래밍 언어에서는 블록( { } ) 안에 있는 코드는 유효범위를 가지며, 일반적으로 유효범위 내부의 변수는 외부에서 사용 불가능합니다.

 

즉, 블록( { } )을 기준으로 범위가 생성되기 때문에 블록 유효범위(block scope)라고 부르는데, JavaScript는 블록 유효범위라는 개념이 존재하지 않습니다.

 

대신, 함수 유효범위라는 개념이 존재합니다.

function funcTest() {
  // 변수 x는 funcTest 함수 어디서든 사용 가능합니다.
  var x = 0; 
  
  if(x === 0) {
    // 변수 y는 블록( { } )으로 감싸져있지만, funcTest 함수 어디서든 사용 가능합니다.
    var y = 10; 
    
    // 변수 z는 for문안에 있지만, funcTest 함수 어디서든 사용 가능합니다.
    for (var z = 0; z < y; z++) {
      console.log(z);
    }
  }
  
  // 블록으로 감싸져있는 변수 y와 z를 출력합니다.
  console.log('y : ' + y); 
  console.log('z : ' + z);
}

funcTest();

 

함수 유효범위(function scope)는 함수 내부에서 선언된 변수는 함수 전체에 걸쳐 유효하다는 의미입니다.

변수가 선언되기 전에도 유효합니다.

var x = 1000; 

function funcTest() {
  console.log('x : ' + x); 
  // x : undefined
  
  var x = 10; 
  
  console.log('x : ' + x); 
  // x : 10
}

funcTest();

 

함수 내부에서 변수 x가 선언되기도 전에 사용되었기 때문에 전역 변수 x의 값 1000이 출력될거라 예상했지만, undefined가 출력되었습니다.

 

호이스팅(hoisting)은 끌어올림이라는 뜻을 가지며, JavaScript에서 함수 내부의 모든 변수를 맨 위로 '끌어올린' 것처럼 동작합니다.

 

위 코드의 funcTest 함수는 아래와 같이 동작합니다.

변수 x는 맨 꼭대기에 호이스팅(hoisting)되고나서 값이 설정됩니다.

function funcTest() {
  var x;
  console.log('x : ' + x); 
  x = 10; 
  console.log('x : ' + x); 
}

 

변수를 최상단으로 끌어올리는 호이스팅은 장점도 존재하지만, 단점도 존재합니다.

 

함수의 코드가 1000줄이고 950번째 라인에 변수를 선언한 코드를 분석한다고 가정해봅시다.

 

호이스팅에 의해 에러는 나지 않지만, 코드를 예측하기가 어렵다는 문제가 발생합니다.

 

편리하다는 이유로 가독성이 떨어지는 코드를 작성하지 않도록 주의합시다.

반응형

댓글