'자바스크립트' 태그의 글 목록 :: 잡다한 프로그래밍
반응형

자바스크립트의 호이스팅에 대해 알아보는 시간을 가진다.


1. 호이스팅 (Hoisting)

- 자바스크립트에서 선언하는 변수값은 모두 유효 범위의 최상단으로 선언된다 = 즉 나는 밑에서 선언했지만 제일 상단에서 선언한것처럼 동작한다. 라는 의미를 가진다.

  • 자바스크립트 Parser가 함수 실행 전 해당 함수를 한번 훑는과정을 거친다.
  • 함수 안에 존재하는 변수/함수 선언에 대한 정보를 내부적으로 끌어올려서 처리한다(코드상의 변화가 있지는 않음)

 호이스팅의 대상

  • var 변수 선언, 함수 선언문에서 호이스팅이 일어난다.
    • let, const 에서는 호이스팅이 일어나지 않음 (ES6에서 개선) ※ 호이스팅은 일어나나, 발생하지 않는것처럼 참조 에러가 발생함

변수는 어떤식으로 생성 될까?

1. 변수의 선언

  • 변수를 실행 컨텍스트의 변수 객체에 등록함.

2. 초기화 단계

  • 변수 객체에 등록된 변수를 위한 공간을 메모리에 확보한다.
  • 이때 변수는 undefined로 초기화 된다.

3. 할당 단계

  • 실제 undefined로 초기화된 변수에 값을 할당한다.

 

앞서 말한 var키워드는 선언, 초기화가 한번에 이루어진다. 즉 스코프에 변수를 등록하고 공간을 확보한 후 undefined로 초기화한다. 하지만 let키워드는 선언과 초기화가 분리되어 진행되므로, 초기화 이전에 접근하면 에러가 발생한다.

 

- 앞서 이론적인 부분을 코드적으로 이해해보도록 하자

변수 선언에서의 호이스팅 예시

console.log(val); //선언 + 초기화
val = 'text'; //선언 + 초기화 + 할당
var val = 'hi';

- 해당 코드를 js가 아닌 다른 언어로 생각했을경우 1 번째 line에서 에러가 발생해야한다 하지만 결과는 undefined값이 찍힌다. 이유는 앞선 선언 + 초기화가 되어있기 때문이다

console.log(val); // 호이스팅에 의해 끌어올려졌지만 초기화는 안된 상태
let val = 'hi'

let을 사용하게되면 선언만 이루어지고 초기화는 되지않아서 에러가 발생한다.

 

함수 선언에서의 호이스팅 예시

test(); // 함수 선언문 정상동작 호이스팅 O
test2(); // 함수 표현식 오류 발생 호이스팅 X 

function test() {
	console.log('test');
}

var test2 = function() {
	console.log('test2');
}

- 함수 선언문같은 경우 호이스팅이 된다. 하지만 함수 표현식의 경우 호이스팅이 이루어지지 않는다.

함수 선언문의 경우 = 함수 전체가 최상단으로 호이스팅 된다. 하지만 함수 표현식의 경우 변수가 호이스팅 되기때문에 에러가 발생한다

 

클래스의 호이스팅

그렇다면 ES6에 추가된 클래스는 어떨까? (let, const가 변수 선언 전에 사용하면 에러가발생하듯 class의 경우도 오류가 발생할까?)

let test = new Test('hi'); // ReferenceError: Person is not defined
console.log(peter);

class Test {
  constructor(val) {
    this.val = val;
  }
}

생각한 대로 클래스는 ReferenceError를 내뱉는다. 함수 선언문의 경우 호이스팅 되어 이전에 사용할 수 있었지만. ES6에서 추가된 클래스의 경우는 호이스팅 되어도 초기화가 되지않기 때문에 (let, const 처럼) 에러를 내뱉는다.

 

- 마찬가지로 클래스 표현식 let val = class Test {....} 로 정의할 경우도 에러를 발생시킨다.

 

이상 간단한 호이스팅 정리였다.

반응형
반응형

1. 변수 선언 차이

#1) var 변수

var을 사용하게 되면 다음과 같이 같은 이름의 변수를 한 번 더 선언해도 다른 값이 출력된다. 이는 유연한 변수 선언이 가능하지만 코드량이 많아진다면 어떻게 사용될지 파악하기 힘들고 값이 바뀔 우려가 있다.

    var test = 'test1'
    console.log(test) // test1

    var test = 'test2'
    console.log(test) // test2

 

#2) let, const 변수

다음처럼 같은 이름으로 변수를 선언할 경우 이미 선언된 변수라고 에러가 발생한다.

    let test = 'test1'
    console.log(test) // test1

    let test = 'test2'
    console.log(test) 
    // Uncaught SyntaxError: Identifier 'test' has already been declared

 

#3) let const 차이

다음과 같이 let은 같은이름으로 변수는 선언할 수 없지만 같은 변수에 다른 값을 재할당할 수 있다.

    let test = 'test1'
    console.log(test) // test1

    name = 'change'
    console.log(test) //change

 

하지만 const는 let과 달리 같은 변수에 다른 값을 재할당 할 수 없다.

    const test = 'test1'
    console.log(test) // test1

    const test = 'test2'
    console.log(test) 
    // Uncaught SyntaxError: Identifier 'test' has already been declared

    test = 'change'
    console.log(test) 
    //Uncaught TypeError: Assignment to constant variable.

 

즉 var = 재선언 재할당 가능, let 재선언 불가 재할당 가능, const 재선언, 재할당 불가이다.


2. 호이 스팅

호이 스팅이란? _참고

 

var, let에는 다음과 같은 호이스팅 차이가 존재한다. var은 test가 없어도 호이스팅 되어 undefined로 결과가 찍히지만 let은 호이스팅 되지 않아 에러가 발생한다.

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

	console.log(test1); // Error: Uncaught ReferenceError: test1 is not defined
	let test1;

3. 마무리

기본적으로 변경이 없는 변수일 경우 const를 사용하고 재할당이 필요한 경우라면 let을 사용하는 것이 좋을 것 같다

반응형

+ Recent posts