본문 바로가기
PROGRAM/Script Language

[javascript] 호이스팅 (hoisting) 이란?

by ojava 2019. 5. 14.
반응형

호스팅(hosting)은 많이 들어봤는데 호이스팅(hoisting) 은 생소한 단어였다.

호이스팅의 개념은 javascript 변수 범위를 설명하면서 자주 언급되었는데 오늘 해당 용어의 의미와 어떤 개념인지 확인해보도록 하자.

 

 

[javascript] 호이스팅 (hoisting) 이란?

 

호이스트(hoist)는 건축/건설이나 화물 운반에 사용되는 장비로 화물 등을 들어올리는 업무를 수행한다.

즉, 아래에 위치한 것을 위로 끌어올리는 역할을 하는 장비인데 이 단어 자체로도 '들어올리다' 라는 의미를 가지고 있다.

 

 

javascript에서의 호이스팅(hoisting)은 코드에 선언된 변수 및 함수를 코드 상단으로 끌어올리는 것을 말하며

이는 변수 범위가 전역 범위인지 함수 범위인지에 따라 다르게 수행될 수 있다.

함수 내에서 선언한 함수 범위(function scope)의 변수는, 해당 함수의 최상위로.

함수 밖에서 선언한 전역 범위(global scope)의 전역 변수는 스크립트 단위의 최상위로 끌어올려진다.

 

2019/05/13 - [PROGRAM/JavaScript / HTML] - 변수 선언 방식의 차이 : var name / $name

 

 

 

여기서 헷갈릴 수 있는 부분은 변수의 선언과 할당 내용 모두를 상단으로 끌어올리는 게 아니라, 선언부분만 분리하여 최상위로 끌어올린다. 선언된 변수에 값을 할당하는 내용은 원래 그 라인에 있다.

(물론 최초 선언 시 초기화한 경우에도 선언과 할당으로 분리하여 호이스팅한다.)

 

 

변수 선언과 할당 중 선언부만 호이스팅한다는 내용을 우선 확인해보자.

noDefine();

function noDefine() {
  // 변수 선언 및 할당 이전에 호출 테스트
  console.log("not defined : " + name);
  var name = "ojava";
  // 변수 초기화 이후 값 확인
  console.log("defined : " + name);
}

 

위 코드의 결과를 예상해보면 첫번째 콘솔 로그에서 사용된 name은 선언되지 않았기 때문에 오류가 발생할 것 같지만, 오류 없이 아래와 같은 로그가 찍힌다.

 

not defined : undefined
defined : ojava

 

 

내부적으로 자바스크립트엔진에서 var name = "ojava"를 var name;name = "ojava"; 로 분리하여

변수 선언부를 함수 상단으로 끌어올려서 선언해버리므로 오류가 발생하지 않는 대신 값이 정의되지 않았다는 의미로 undefined를 반환하는 것을 알 수 있다.

noDefine();

function noDefine() {
  var name; // 변수 선언부를 호이스팅함 (위로 끌어올림)
  console.log("not defined : " + name);
  name = "ojava"; // 값 할당은 원래 그 위치에 그대로!
  console.log("defined : " + name);
}

 

단, 이 경우 변수 선언하는 var를 생략하는 경우 예상치 않은 결과를 내뱉으므로 주의해야 한다.

noDefine 이라는 함수 범위의 변수를 생성하려했으나, name = "ojava"의 형태로 선언한 경우 이상한 결과가 반환된다.

 

noDefine();

function noDefine() {
  console.log("not defined : " + name);
  // var name = "ojava";
  name = "ojava"; // 변수 선언 명령어 없이 name 변수에 할당함
  console.log("defined : " + name);
}
not defined : ojava
defined : ojava

 

오류가 발생하지 않았을뿐 아니라, 변수를 할당하기 전임에도 이미 할당된 값으로 반환해버린다.

함수 내에서 변수 선언 명령어를 제외하고 선언 시 전역 변수의 형태로 사용됨에 주의하자!

이 경우는 함수에서 선언 명령어 없이 초기화 한 값을 전역 변수로 사용하고 있음을 볼 수 있으며, 예상하지 못한 결과값을 반환할 수 있으므로 주의해야 한다.

 

 

 

 

그리고 위의 예제에서 계속적으로 함수 선언보다 호출이 더 먼저 일어나고 있음에도 에러 없이 코드가 실행됨을 알 수 있다. (일단 내가 돌려봤을 때 이상없이 잘 돌아갔다.)

 

함수 선언 내용의 경우 선언한 위치와 관계없이 항상 최상단으로 호이스팅되므로 코드상에서 함수를 선언한 위치보다 먼저 호출하더라도 이상없이 호출된다.

단, 함수 호이스팅은 선언 방식이 함수 선언식 (function declarations) 인 경우에만 적용된다.

 

함수 선언 방식은 기본적으로 크게 두 가지로 나뉜다. 

function 명령어와 함께 함수명을 지정하고 function body 내용을 구성하는 함수 선언식(function declarations)

변수에 함수를 할당하는 형태의 함수 표현식(function expressions)이 있다.

 

 

함수 선언 방식에 대한 내용은 다음 포스팅으로 별도 다룰 예정이지만 간단한 사례를 들면 아래와 같다.

// 함수 선언식 (function declarations)
function getNames() {
   var name = $("input:text").val();
}

// 함수 표현식 (function expressions)
var checkAge = function() {
   if($("#age").val() < 20) {
      alert("20세 이상만 신청 가능합니다.");
   }
}

 

변수 및 함수 호이스팅 등 자바스크립트 작동방식을 이해해두면

예상치못한 에러가 나더라도 금방 고치고 칼퇴하는데 도움이 될 것으로 생각된다 ㅎ_ㅎ

 

 

 

 

 

* 참고

http://chanlee.github.io/2013/12/10/javascript-variable-scope-and-hoisting/

 

자바스크립트의 변수범위와 호이스팅

이 글에서, 우리는 자바스크립트 변수의 범위(scope)와 호이스팅(hoisting), 그리고 이 두가지의 특징에 관해 배워보겠습니다. 자바스크립트의 변수범위와 호이스팅이 작동하는 원리를 이해하는것은 필수적입니다. 이 두가지 컨셉은 직관적이면서도 이해하기가 쉽지 않습니다. 거기에는 미묘한 차이가 있으며, 자바스크립트 프로젝트에서 성공하기 위해서는 반드시

chanlee.github.io

https://developer.mozilla.org/ko/docs/Glossary/Hoisting

 

Hoisting

호이스팅(hoisting)은 ECMAScript® 2015 언어 명세 및 그 이전 표준 명세에서 사용된 적이 없는 용어입니다. 호이스팅은 JavaScript에서 실행 콘텍스트(특히 생성 및 실행 단계)가 어떻게 동작하는가에 대한 일반적인 생각으로 여겨집니다. 하지만 호이스팅은 오해로 이어질 수 있습니다. 예를 들어, 호이스팅을 변수 및 함수 선언이 물리적으로 작성한 코드의 상단으로 옮겨지는 것으로 가르치지만, 실제로는 그렇지 않습니다. 변수 및 함수 선언

developer.mozilla.org

 

반응형