Scope/Closure/Hoisting (스코프/클로저/호이스팅)

Ryeokyeong Hong·2022년 4월 21일
0

Javascript

목록 보기
10/15

Scope(스코프)

  • 사전적 의미 : 범위
  • 변수에 접근할 수 있는 범위 / 변수가 영향을 끼칠 수 있는 범위
  • 크게 나누면 전역스코프/지역스코프. 세세하게 나누면 함수 레벨 스코프/블록 레벨 스코프(ES6)/렉시컬 스코프

전역 스코프(Global scope)/지역 스코프(Local scope)

  • 지역 스코프에서 선언된 변수는 전역 스코프에서 사용이 불가능함
  • 특정 함수내에서 선언된 지역 변수는 전역 변수보다 우선순위가 높음(전역 변수는 전역 스코프를 갖음)
  • 함수 내에서 전역 변수에 새로운 값을 할당해 준다면 전역 변수는 새로운 값으로 수정이 됨
  • 전역 변수를 사용하면 변수이름이 중복되거나 의도치 않게 변수 재할당이 발생 할 수 있으므로 지양함

함수 레벨 스코프

  • var로 선언된 변수
  • 함수 선언식으로 만들어진 함수는 함수 레벨 스코프를 지님
  • 변수는 함수 내부 전체에서(만) 유효한 식별자가 됨

블록 레벨 스코프

  • let, const(ES6)는 블록 레벨 스코프 변수를 만들어 줌
  • 블록이란 -> if/else, while/for 내부로 정해진 범위
  • let, const가 도입되면서 var는 사용하지 않음 -> let으로 대체가능하며 var는 함수 전체에 대한 스코프를 가짐

렉시컬 스코프

  • 호출 스택과 관계없이 각각의 소스코드가 작성된 그 문맥을 기준으로 데이터를 대응하며 그 대응은 런타임에서 변하지 않음 (this는 제외)
var x = 'global';

function func1(){
	var x = 'local';
    func2();
}

function func2(){
	console.log(x);
}
func1();			//결과값 : global
func2();			//결과값 : global

Closure(클로저)

  • 사전적 의미 : 포섭
  • 함수+함수를 둘러산 환경(렉시컬 환경)
  • 함수가 생성되는 시점에 생성됨 -> 함수가 생성될 때 그 함수의 렉시컬 환경을 포섭하여 실행될 때 함께 이용됨
  • 클로저가 사용되는 경우
    - 현재 상태를 기억하고 변경된 최신 상태를 유지해야 될 때
    - 전역 변수의 사용을 줄이고 싶을 때
    - 어떠한 정보를 숨기고 싶을 때

유명한 반복문 클로저

function count() {
    var i;
    for (i = 1; i < 10; i += 1) {
        setTimeout(function timer() {
            console.log(i);
        }, i*100);
    }
}
count();			//결과값 : 10이 9번 출력됨

/**
	1) timer는 클로저로 항상 상위 스코프인 count에게 i 를 알려달라고 요청함
    2) timer는 그러고 0.1초 후 호출됨
    3) 첫 0.1초가 지날 동안 이미 i는 10이 됨
    4) timer는 0.1초 주기로 호출할 때마다 count에서 i를 요청함
    => timer는 이미 10이 되어비린 i만 출력
**/
  • 의도대로 1~9까지 차례대로 출력하는 방법
    1) 새로운 스코프를 추가하여 반복 시마다 그 곳에 각각 따로 값을 저장하는 방식

     function count() {
         var i;
         for (i = 1; i < 10; i += 1) {
             (function(countingNumber) {
                 setTimeout(function timer() {
                     console.log(countingNumber);
                 }, i * 100);
             })(i);
         }
     }
     count();

    2) ES6에서 추가된 블록 스코프 이용하는 방식

    ```
    function count() {
         'use strict';
         for (let i = 1; i < 10; i += 1) {
             setTimeout(function timer() {
                 console.log(i);
             }, i * 100);
         }
     }
     count();

Hoisting(호이스팅)

  • 사전적 의미 : 끌어올림
  • 자바스크립트 엔진은 코드를 컴파일 -> 인터프리팅의 순으로 처리하는데,
    컴파일 단계에서 var a=2; 라는 코드를 두 개의 구문으로 분리하여 봄
    => var a; //변수 선언 단계
    => a=2; //변수 초기화 단계
    (참고 > 컴파일 : 전체소스코드를 보고 명령어를 수집하고 재구성 / 인터프리팅 : 소스코드의 각 행을 연속적으로 분석하며 실행)
  • 선언 단계에서는 그 선언이 코드에서 어디에 위치하든 해당 스코프의 컴파일 단계에서 처리함
  • 선언 단계가 스코프의 꼭대기로 끌어올려지는 것 = 호이스팅
  • 해당 값을 선언하기 전에 참조하는 것이랑 헷갈리면 안됨
function foo() {
  a=2;
  var a=2;
  console.log(a);		//결과값 : 2 (선언부가 호이스팅 됨)
}


function foo(){
  console.log(a);
  var a=2;				//결과값 : undefined (선언 전 참조됨)
}

/**
	블록 스코프인 ES6의 let도 호이스팅 되지만, 선언 전에 참조할 경우 undefied를 반환하지 않고 ReferenceError를 발생시킴
**/

.
.
.
.

참조
https://yunzema.tistory.com/362
https://meetup.toast.com/posts/86
https://m.blog.naver.com/jaemin-jeong/221877574892

0개의 댓글

관련 채용 정보