As i wish

[JavaScript] Scope와 Hoisting 본문

JavaScript

[JavaScript] Scope와 Hoisting

어면태 2019. 7. 8. 17:08

안녕하세요. 오늘은 JS에 기본 개념인 scope, hoisting에 대하여 포스팅 해보겠습니다.

JS 강좌를 듣고 있으면 scope, hoisting, closure 등등 알수 없는 말들이 많은데요. 

개념을 확실히 잡고 가야할듯 합니다.

 

Scope (유효 범위)

변수나 함수에 대한 유효 범위입니다. 즉, 변수와 매개변수의 접근성과 생존기간을 의미 합니다. 

 

- Global Scope (전역 스코프)

말 그대로 전역 변수 라고 생각하면 쉽겠네요.

        var a = 'text';

        function foo() {
          console.log(a);
        }

        foo(); // text
        console.log(a); // text

이렇게 선언하면 스코프가 코드 모든곳이 됩니다. 심지어 선언한 함수 안에서도요.

 

- Local Scope (지역 스코프)

이에 따라 특정 부분에서만 사용할 수 있는 변수를 지역 스코프에 있다고 할 수 있습니다.

자바스크립트에서는 두가지가 존재하는데 function scope(함수 스코프), block scope(블록 스코프) 입니다.

 

function level scope (함수 레벨 스코프)

자바스크립트에서 var키워드로 선언한 변수는 함수 스코프, 즉 함수 내부 전체에서 유효한 값을 가지게 됩니다.

        function foo() {
          if (true) {
            var a = 'text';
          }
          console.log(a); // text
        }

        foo();

위 처럼 if 문이 종료 되어도 if 문 안에서 생성된 변수가 동작 하는 것을 보실 수 있죠. 함수 스코프를 가지고 있기 때문에 함수 안에서는 어디든 동작이 가능합니다.

 

block level scope (블록 레벨 스코프)

이에 따라  ES6 에서는 let, const 를 이용하여 블록 스코프를 만들어 줍니다.

        function foo() {
          if (true) {
            let a = 'text';
            console.log(a); // text
          }
          console.log(a); // Error: a is not defined
        }

        foo();

위 처럼 에러가 나는것을 볼 수 있습니다. 이는 변수가 if 문 안에서만 유효하기 때문이죠. 그렇기 때문에 if 문 안에서는 정상 동작합니다.

 

- Lexical Scope (렉시컬 스코프)

        var x = 1;

        function foo() {
          var x = 10;
          bar();
        }

        function bar() {
          console.log(x);
        }

        foo(); // 1
        bar(); // 1

위 예제의 실행 결과는 함수 bar의 상위 스코프가 무엇인지에 따라 결정된다. 두가지 패턴을 예측할 수 있는데 첫 번째는 함수를 어디서 호출하였는지에 따라 상위 스코프를 결정하는 것이고 두 번째는 함수를 어디서 선언하였는지에 따라 상위 스코프를 결정하는 것이다. 첫번째 방식으로 함수의 상위 스코프를 결정한다면 함수 bar의 상위 스코프는 함수 foo와 전역일 것이고, 두번째 방식으로 함수의 스코프를 결정한다면 함수 bar의 스코프는 전역일 것이다.

 

프로그래밍 언어는 두가지 방식으로 함수의 상위 스코프를 결정하는데, 하나는 동적 스코프 (Dynamic scope) 라고 하고 두 번째 방식은 렉시컬 스코프(Lexical scope) 또는 정적 스코프 (Static scope) 라고 합니다. 자바스크립트를 포함한 대부분 언어가 렉시컬 스코프를 따르죠.

렉시컬 스코프는 함수를 어디서 호출하는지가 아니라 어디에 선언하였는지에 따라 결정됩니다. 따라서 위 예제의 함수 bar는 전역에 선언되어있고, 따라서 함수 bar의 상위 스코프는 전역이므로 bar 안에 있는 x는 1을 따라가는거죠.

 

Hoisting (호이스팅)

호이스팅이란 변수의 정의가 그 스코프에 따라 선언과 할당으로 분리되는 것을 의미합니다.

        function foo() {
          a = 'text';
          var a;
          console.log(a);
        }

        foo(); // text

위 예제가 호이스팅에 다시 해석된 코드는 다음과 같습니다.

        function foo() {
          var a;
          a = 'text';
          console.log(a);
        }

        foo();

한번 더 예를 들어 보겠습니다.

 

        function foo() {
          console.log('1: ' + a);
          var a = 'text';
          console.log('2: ' + a);
        }

        foo();
        // 1: undefined
        // 2: text

위 코드를 호이스팅 해석 해보면

        function foo() {
          var a;
          console.log('1: ' + a);
          a = 'text';
          console.log('2: ' + a);
        }

        foo();

다음과 같죠, 호이스티으로 var a의 선언이 최상위로 변경되기 때문에, 첫 번째 로그가 출력 될 때에는 undefined, 두 번째 로그는 'text' 가 됩니다.

'JavaScript' 카테고리의 다른 글

[JavaScript] splice, slice, split  (0) 2019.08.13
[JavaScript] Closure  (0) 2019.07.08
[You don't know JS] - 비동기성: 지금과 나중  (0) 2019.06.15
[You don't know JS] - 작동 위임  (0) 2019.06.07
[You don't know JS] - 프로토타입  (0) 2019.05.29
Comments