티스토리 뷰

때는 데브코스 면접날..
Lia님이 내가 최근에 스터디를 했던 내용 중에 호이스팅에 대해 물어보셨다.

Lia : "최근에 모던자바스크립트 스터디 하셨다고 했는데 호이스팅이 뭔지 짧게 설명 해주실 수 있나요?"

나 : "어.. 변수 선언할 때 끌어올림 현상.. 입니다..."

다행히 정말 운좋게 합격해서 강의를 듣는중..

이선협 강사님 : "var를 사용할 순 있지만 권장하진 않습니다. 그 이유는 호이스팅이라는 자바스크립트 특징 때문입니다. 도대체 호이스팅이 뭐길래 var를 안쓰는지는 오늘 숙제로 남기도록 하겠습니다. 🤗"

호이스팅에 대해 알아보자^^

 

호이스팅

Hoisting (무언가를 들어올리다 / 끌러올리다) 라는 의미로,
인터프리터가 변수와 함수의 메모리 공간을 선언 전에 미리 할당하는 것을 의미한다.
예제로 확인해보자.

함수의 호이스팅

자바스크립트에서 함수를 어떤식으로 선언하느냐에 따라 다르다.

// 함수 선언식 호이스팅됨 O
console.log(square(5); // 25
function square(x) {
  return x * x;
}


// 함수 표현식 호이스팅 안됨 X
console.log(add(1,2)); // TypeError: add is not a function
var add = function(a,b) {
  return a + b;
}


// new Function 호이스팅 안됨 X
showName();	// TypeError: showName is not a function
var showName = new Function("", console.log("KIM"));

 

변수의 호이스팅

var 키워드로 변수를 선언해야 호이스팅 현상이 일어나는 것을 "볼 수 있다"

// var 키워드 사용 시 호이스팅됨 O
console.log(a); // undefined
var a = "Hello";
console.log(a); // Hello


// var 키워드 미사용 시 호이스팅 안됨 X
console.log(a); // ReferenceError: a is not defined
a = "Hello";
console.log(a);


// let, const 키워드 사용 시 호이스팅 둘 다 안됨 X
console.log(a);	// ReferenceError: Cannot access 'a' before initialization
console.log(b);
let a = "hello";
const b = "world";
console.log(a);
console.log(b);

그럼 여기서 의문이 든다.

"let이랑 const는 호이스팅이 안일어나니까 그냥 그거 두 개 쓰면 되지 않나? 🙄"

라는 의문이 들 수 있다.
하지만 let과 const도 호이스팅 대상이다.

다만 var와 달리 호이스팅 시 undefined로 변수를 초기화 하지 않기 때문에 예외처리 되면서 에러를 던져준다.

 

호이스팅 주의할 점

  • 가독성과 유지보수를 위해 호이스팅이 일어나지 않도록 한다.
  • 함수와 변수를 가급적 코드 상단부에 선언한다.
  • let / const 를 사용한다.

 

스코프 (Scope, 유효범위)

스코프란?
ES5까지는 함수 레벨 스코프까지 지원했다.
함수 선언식으로 만들어진 함수 내부 전체에 유효한 식별자가 되어 아래 코드 처럼 에러 없이 콘솔이 찍힌다.

// 함수 레벨 스코프
function foo() {
  if(true) {
    var color = "blue";
  }
  console.log(color); // blue
}

하지만 ES6부터는 블록 레벨의 스코프를 지원한다.
아래 코드처럼 letconst 키워드를 통해 블록 레벨 스코프 사용이 가능하다.

function foo() {
  if(true) {
    let color = "blue";
    console.log(color);	// blue;
  }
  console.log(color); // ReferenceError: color is not defined
}

전역 범위에 변수가 선언된 경우 전역 변수라고 하며 Global Scope라고 한다.
블록 내부에 변수가 선언된 경우 지역 변수라고 하며 Local Scope라고 한다.

const a = 5;	// Global Scope
{
  const b = 3;	// Local Scope
  conosle.log(a,b);
  // 5 3
}
console.log(a,b);
// Error

 

 

클로저 (Closure)

클로저란?
함수가 선언된 환경의 스코프를 기억하여 함수가 스코프 밖에서 실행될 때에도 기억한 스코프에 접근할 수 있게 만드는 문법

자바스크립트에선 함수가 실행이 완료되어도 메모리를 바로 해제하지 않는다.
변수가 여전히 다른 함수에서 참조되고 있다면 메모리에 남겨두기 때문에 참조 가능하다.
이러한 성질 때문에 아래와 같은 코드가 실행될 수 있다.

function testFunc() {
  let localVar = 2;
  
  return function() {
    console.log(`localValr = ${lcalVar}`);	// testFunc 지역 변수 참조
  }
}

let returnedFunc = testFunc();
returnedFunc();	// localVar = 2

이런 클로저를 유용하게 사용하는 방법 중 하나는 은닉화이다.
아래의 코드처럼 내부 변수와 함수를 숨길 수 있다.

function Counter() {
  let privateCounter = 0;
  function changeBy(val) {
    privateCounter += val;
  }
  
  return {
    increment: function () {
      changeBy(1);
    },
    decrement: function () {
      changeBy(-1);
    },
    value: function() {
      return privateCounter;
    },
  };
}

const counter = Counter();

console.log(counter.value()); // logs 0
counter.increment();
counter.increment();
console.log(counter.value()); // logs 2
counter.decrement();
console.log(counter.value()); // logs 1

자바와 같은 몇몇 언어들은 메소드를 프라이빗으로 선언할 수 있는 기능이 있다.
하지만 자바스크립트는 태생적으로 이런 방법이 없어서 클로저의 성질을 이용하여 프라이빗 메소드를 흉내내는 것이 가능하다고 한다. 🙄

 


프로그래머스 데브코스

 

[3기] K-Digital Training: 빅데이터 플랫폼 프론트엔드 엔지니어링

🚀프론트엔드 데브코스 모집 마감 미리 ‘오픈 알림 신청’하고 내년에 오픈 예정인 4기에 도전하세요! 오픈 알림 신청 📢[오리엔테이션 안내] 10월 12일(수) 오후 16시에 오리엔테이션 안내 메

school.programmers.co.kr

MDN 클로저

 

클로저 - JavaScript | MDN

클로저는 함수와 함수가 선언된 어휘적 환경의 조합이다. 클로저를 이해하려면 자바스크립트가 어떻게 변수의 유효범위를 지정하는지(Lexical scoping)를 먼저 이해해야 한다.

developer.mozilla.org

손수림님 벨로그

 

JavaScript - Hoisting(호이스팅)에 대해 알아보자

호이스팅 (Hoisting) 사전적 정의 : 끌어 올리기 JavaScript에서의 Hoisting : 변수의 정의가 그 범위에 따라 선언과 할당으로 분리되는 것을 의미한다. 즉, 변수가 함수 내에서 정의되었을 경우, 선언부

velog.io