[CS] 스코프 / 클로저 / 실행컨텍스트에 대하여

Logun·2023년 8월 23일
0

CS

목록 보기
7/17
post-thumbnail

✅ 스코프


Scope 변수 참조의 유효범위로 전역 스코프, 지역스코프와 나뉘어 지는데, 지역 스코프는 안에서 추가로 함수 레벨 스코프, 블록 레벨 스코프로 나뉘어 진다.

개발자 모드의 source 탭에서 확인이 가능하다.

  • 전역 스코프 (global)
    전역 스코프와 지역스코프 안에서 모두 사용 가능

  • 지역 스코프 (Local)

    • 함수 레벨 스코프
      const sum = function () {} script라는 곳에 생성

    • 블록 레벨 스코프
      if(){} block라는 곳에 생성

    • 함수 레벨 스코프와 블록 레벨 스코프의 내부를 Local이라고 한다.

  • 스코프 체인 (scope chain)
    스코프를 타고타고 올라가서 할당된 변수를 찾는 것을 의미한다. 글로벌 스코프 안에 지역스코프 안에 지역스코프가 생길 수 있다. 즉, 다른 스코프안에 스코프들을 생성할 수 있다.

  • 변수 var
    블록 레벨 스코프 무시가 가능하여, 밖에서 참조 가능 하기 때문에 사용을 지양한다.

✅ 클로저


  • 클로져

    • 전역변수가 많으면 어디에서든 실수로라도 접근을 할 수 있기 때문에 최대한 전역변수를 줄여서 코드를 해야한다.

    • 클로저는 내부에 선언된 함수가 외부함수의 지역변수를 사용해 줬을 때만 클로저라고 선언된다.

  • 은닉화
    클로저를 이용하여 내부 변수와 함수를 숨길 수 있다.

    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()); // 0
    counter.increment();
    counter.increment();
    console.log(counter.value()); // 2
    counter.decrement();
    consoel.log(counter.value()); // 1
  • 코드예시

        let txtField = document.querySelector('.txt');
        let toggleBtn = document.querySelector('.toggle');
    
        let toggle = (function () {
          let isVisable = false;
    
          // 1.클로저를 반환
          return function () {
            txtField .style.display = isVisable ? 'block' : 'none';
            // 3. 상태 변경
            isVisable = !isVisable;
          };
        })();
    
        // 2. 이벤트 프로퍼티에 클로저를 할당
        toggleBtn.onclick = toggle;
  • 코드 설명

    • 즉시 실행함수가 함수를 반환한 뒤 바로 소멸된다.
      이때 반환된 힘수는 자신이 생성됐을때의 Lexical 환경에 속한 변수인 isVisable을 기억하는 클로저가 된다.

    • 클로저가 기억하는 변수인 isVisable은 txt 표시 상태를 나타낸다. 클로저를 버튼 이벤트 프로퍼티에 할당을 했다. 이제 이 클로저를 제거하지 않는한 isVisable 은 소멸되지 않는다.

    • 버튼 클릭시 클로저가 호출되게되는데 이때 txt요소의 표시 상태를 나타내는 변수인 isVisable 값이 변경이 되게 된다.

    • 이 변수는 클로저에 의해 참조 되고 있기 때문에 변경된 최신 값을 계속 유지할 수가 있다.

클로저를 잘 알아야하는 이유는 유용하게 사용하기보단 알기 힘든 버그를 잘 수정하기 위해서이다.

  • 에러코드
    출력 결과로 12345가 아닌, 55555가 나온다.

    function counting() {
     	let i = 0;
      for (i = 0; i < 5; i += 1) {
      	setTimeout(function () {
        	console.log(i);
        }, i * 100);
      }
    }
  • 해결방법 1
    즉시 실행 함수를 이용한다. 루프마다 클로저 생성

    function counting() {
    	let i = 0;
      	for (i = 0; i < 5; i +=1) {
        	setTimeout(function () {
              console.log(number);
            }, number * 100);
        }
    }
  • 해결방법 2
    let을 이용한다. let은 블록수준 스코프기 때문에 매 루프마다 클로저가 생성된다.

    	function counting() {
        	for (let i = 0; i < 5; i += 1) {
            	setTimeout(function () {
                	console.log(i);
                }, i * 100);
            }
        }

✅ 호이스팅


코드를 한 번 해석하는 과정을 거치는데, 그때 선언 단계가 위로 올라가게된다. 선언부가 위로 올라 가고 초기화 단계까지 실행되는 형태를 호이스팅이라고 한다. 이렇게 될 경우에는 값이 undefined로 잡혀 에러를 미리 방지 할 수 없다.

  • 변수 선언 단계

    • 선언단계
      선언한 변수를 식별자(변수명)가 담기는 객체에 할당하는 단계

    • TDZ (Temporal Dead Zone)
      선언단계와 초기화단계 사이에 있는 구역이며, Let과 Const는 선언단계와 초기화단계가 분리 되어 TDZ에 머무르게 된다. 할당되는 변수를 만나기 전까지 TDZ에 있음

    • 초기화단계
      변수에 할당할 메모리 공간을 부여하는 단계

    • 변수var
      선언과 초기화단계 둘 다 되어버리다. 메모리를 할당 받아 버려 에러를 검출하기 어렵다.

    • 할당단계
      정의된 변수에 데이터가 할당되는 단계

    • 함수 선언식
      선언, 초기화, 할당까지 되어버린다.
      function fn1() {}

✅ 실행 컨텍스트


실행 컨텍스트(Execution context)는 우리가 작성한 코드가 실행되는 환경을 말하며, scope, hoisting, this, function, closure 등의 동작원리를 담고 있는 자바스크립트의 핵심원리를 말한다.

  • 글로벌 실행 컨텍스트 (Global Execution Context)

    • 코드가 실행되기 전에 생성이 되며, 함수 내에 없는 코드는 모두 전역 실행 컨텍스트 안에 존재한다.

    • 자바스크립트 엔진은 일부 자바스크립트 코드를 실행할 때마다 글로벌 실행 컨텍스트(Global Execution Context)를 작성한다.

    • 글로벌 실행 컨텍스트의 특징으로는 무조건 하나의 전역 실행 컨텍스트 만이 존재하며, 애플리케이션이 종료될 때 (웹 페이지에서 나가거나 브라우저를 닫을 때)까지 유지하는 것이다.

  • 함수 실행 컨텍스트(Functional Execution Context)

    • 전역 실행 컨텍스트가 생성된 후, 함수가 실행(ex 호출) 될 때마다 새로운 실행 컨텍스트가 작성된다.

    • console.dir()을 사용하면, 개발자 도구로 쉽게 확인이 가능하다.

    • 자기 자신의 스코프(scope)를 제외한 자신과 가장 가까운 변수 객체의 스코프 순으로 접근하는 것을 눈으로 확인할 수 있다.


참고자료
코딩의 성지

profile
로건의 개발이야기

0개의 댓글