개발새발 로그

[2023-09-20] TIL - 스코프와 클로저 본문

TIL

[2023-09-20] TIL - 스코프와 클로저

이즈흐 2023. 9. 20. 18:10

스코프

유효 범위라고도 부르며 변수가 어느 범위까지 참조되는 지를 뜻한다.

- Global Scope

- Local Scope

 

이때 var를 사용하면 개발자가 예상치 못한 오류가 생길 수 있다.

- 호이스팅 되기 때문에 블록 내부에서 선언하더라도 블록 외부 변수 값도 변하게 된다.

 -> var를 가급적 사용하지 않는 이유

 

 

 

클로저

함수가 선언된 환경의 스코프를 기억하여

함수가 스코프 밖에서 실행될 때에도 기억한 스코프에 접근할 수 있게 만드는 문법

 

function outerFunc() {
  var x = 10;
  var innerFunc = function () { console.log(x); };
  innerFunc();
}

outerFunc(); // 10

 

 

은닉화

쿨로저를 이용하여 내부 변수와 함수를 숨길 수 있다.

<!DOCTYPE html>
<html>
  <body>
  <p>클로저를 사용한 Counting</p>
  <button id="inclease">+</button>
  <p id="count">0</p>
  <script>
    var incleaseBtn = document.getElementById('inclease');
    var count = document.getElementById('count');

    var increase = (function () {
      // 카운트 상태를 유지하기 위한 자유 변수
      var counter = 0;
      // 클로저를 반환
      return function () {
        return ++counter;
      };
    }());

    incleaseBtn.onclick = function () {
      count.innerHTML = increase();
    };
  </script>
</body>
</html>

 

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

 

아래의 코드를 보자

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

counting();
// 5 5 5 5 5

- 1 2 3 4 5 가 순차적으로 나올 거라고 예상할 수 있습니다.

- 하지만 5 5 5 5 5 가 출력이 되었는데 이는 setTimeout의 대기시간이 끝나 Callback 함수가 실행된 시점에는 loop가 종료되어 i가 5가 되었기 때문이다.

 

즉 setTimeout 안에 있던 Callback 함수 function() { ~~ } 이 시작되기도 전에 for문이 끝나버려서 i가 5인 상태로 출력이 된 것이다.

 

위를 해결하기 위한 방법이 두가지가 있다.

 

 

해결 방법

1. IIFE를 이용하는 방법

- 즉시실행 함수를 이용하여 loop마다 클로저를 만드는 방법

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

counting();
// 1 2 3 4 5

 

2. let을 이용하는 방법

-let은 블록 수준 스코프기 때문에 매 루프마다 클로저가 생성된다.

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

counting();
// 5 5 5 5 5

 

 

 

https://poiemaweb.com/js-closure

 

Closure | PoiemaWeb

클로저(closure)는 자바스크립트에서 중요한 개념 중 하나로 자바스크립트에 관심을 가지고 있다면 한번쯤은 들어보았을 내용이다. execution context에 대한 사전 지식이 있으면 이해하기 어렵지 않

poiemaweb.com

https://www.youtube.com/watch?v=tpl2oXQkGZs 

 

728x90
반응형
LIST