호스팅(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/
https://developer.mozilla.org/ko/docs/Glossary/Hoisting
'PROGRAM > Script Language' 카테고리의 다른 글
[React 배워보기] 1. SPA Framework와 ECMA 2015 (0) | 2019.06.23 |
---|---|
[javascript] 함수 선언식, 함수 표현식 (0) | 2019.05.21 |
[javascript] 변수 선언 방식의 차이 : var name / $name (0) | 2019.05.13 |
.prop(), .attr()의 차이 (1) | 2019.01.25 |
JSON list 검색 : 특정 필드의 값이 일치하는 JSON Object 추출하기 (0) | 2018.08.24 |