본문 바로가기
javaScript/J Query & 스크립트

클로저 함수

by mooyou 2019. 7. 31.
728x90
300x250
SMALL

클로저 함수는 함수내부에 만든 지역변수가 사라지지 않고 계속 값을 유지하고 있는 상태를말한다.

 

function func(){
	var count=1; // 일반 지역변수
	$("#btn").on("click",
		function(){ //클로저
			count++;
			alert("count = "+count);
		}
	);
}

일반 지역변수의 경우 함수호출이 완료되면 사라지지만 클로저를 이용하면 함수호출이 완료된 후 사라지지 않는 데이터 저장소로 만들 수 있다.

 

function 외부함수(){
	var 변수A;
	function 내부함수(){
		변수A 사용;	
	}
}

클로저는 일종의 현상이기때문에 정해진 문법은 없다.

그래도 표현하자면 위의 문법처럼 내부함수에서 내부함수를 포함하고 있는 외부함수의 변수 A를 사용하는 구조로 표현할수 있고 내부 함수를 클로저함수라고 부른다.

또한 변수A는 클로저 현상에의해 외부함수() 호출이 끝나더라도 사라지지 않고 값을 유지하게 된다.

 

 

+일반함수

    <script>
    
        function addCount(){
            var count=0;
            count++;
            return count;
        }

        document.write("1. count = "+addCount(),"<br>");
        document.write("2. count = "+addCount(),"<br>");
        document.write("3. count = "+addCount(),"<br>");

        /*
         실행결과 :
         1.	Count = 1
         2.	count = 1
         3.	count = 1
         */
         
    </script>

addCount()함수가 호출되면 0으로 초기화된 count 지역변수가 생성되고 증가 연산자 ++ 의해 1이 되고 이 값을 리턴하기 때문에 1이 출력된다. 그리고 모든 구문을 실행한 함수는 종료되면서 함수 내부에 만들어진 count는 메모리에서 사라진다.

따라서 2. 3번 역시 같은 방식으로 샐행되기 때문에 1만 출력된다.

 

 

 

+클로저사용

    <script>
    
        function createCounter(){
            var count=0;
            function addCount(){
                count++;
                return count;
            }
            return addCount;
        }

        var counter = createCounter();

        document.write("1. count = " + counter(),"<br>");
        document.write("2. count = " + counter(),"<br>");
        document.write("3. count = " + counter(),"<br>");


        /*
         실행결과 :
         1.	count = 1
         2.	count = 2
         3.	count = 3
         */

    </script>

createCounter();함수가 호출되면 0으로 초기화된 count 지역변수가 생성되고 내부에 addCount 함수가 리턴되고 마지막으로 createCounter() 함수가 종료되는데 종료되더라도 addCounter()함수 내부에 count변수를 사용하고 있는 상태에서 외부로 리턴되기 때문에 클로저 현상이 발생되어서 count값이 사라지지 않고 남아있게 된다

그래서 값이 증가하기 때문에 1 2 3 이런식으로 값이 나타나게 된다.

 

이렇게 변수가 메모리에서 제거되지 않고 계속 값을 유지하는 상태를 클로저라고 부러고 내부에 있는 함수를 클로저 함수라고 한다.

 

 

클로저 함수는 보통 함수내부에서 리턴값으로 함수를 리턴하는 예제가 많아서 이런경우만 있다고 착각할수 있는데 다음과 같은 경우도 있다.

 

+버튼을 클릭하면 클릭할때마다 1씩 증가시키기

    <script>

        $(document).ready(function() {

            $("#btnStart").click(function () {
                start();
                document.write("시작합니다.");
            });

            function start() {
                var count = 0;
                setInterval(function () {
                    count++;
                    document.write(count);
                }, 1000);
            }
        });
    </script>

start()가 실행되면서 지역변수인 count변수가 만들어지고 setInterval()이 실행된 후 함수가 종료되면 지역변수는 사라져야 하는데 setInterval의 익명함수에서 count를 사용하고 있기 때문에 값이 계속 증가하게 된다.

 

 

- 클로저 사용의 좋은점

연관있는 변수와 기능(중첩함수)를 하나의 함수로 묶어서 독립적으로 실행시킬수가 있다. 함수 내부에 데이터가 만들어지기 때문에 함수 외부에서 수정할 수 없는 보호된 데이터를 만들 수 있다.

(객체지향 프로그래밍에서 이를 private데이터라고 부른다.)

 

 

+클로저가 사용된 탭메뉴

 

	<script>

		$(document).ready(function(){
			// 탭메뉴 코드가 동작할 수 있도록 tabMenu() 함수 호출
			tabMenu("#tabMenu li");
		});


		function tabMenu(selector){
			// 선택 한 탭메뉴를 저장할 변수
			var $selectMenuItem =null;

			// 메뉴 항목에 클릭 이벤트 등록
			$(selector).click(function(){

				// 기존 선택 메뉴 항목이 있으면 비 선택 상태로 만들기
				if($selectMenuItem!=null){
				   $selectMenuItem.removeClass("select");
				}

				// 클릭한 메뉴 항목을 신규 선택 메뉴 항목으로 저장
				$selectMenuItem = $(this);
				// 선택 상태로 만들기
				$selectMenuItem.addClass("select");

			})
		}
	</script>


</head>
	
	<body>
<p>탭메뉴</p>	    
<ul class="tab-menu" id="tabMenu">
	<li class="menuitem1">google</li>
	<li class="menuitem2">facebook</li>
	<li class="menuitem3">pinterest</li>
	<li class="menuitem4">twitter</li>
	<li class="menuitem5">airbnb</li>
	<li class="menuitem6">path</li>
</ul>		

	</body>
</html>

문서가 실행되면 tabMenu 함수를 실행하고 #tabMenu li를 매개변수로 넘겨준다.

tabMenu가 실행되고 var $selectMenuItem =null; 비어있는변수를 생성

매개변수를 클릭을 하면 내부함수가 실행

만약 $selectMenuItem 값이 비어있지 않으면 select 클래스를 지워줘라

그리고 $selectMenuItem에 지금 클릭된 값을 넣고 select 클래스를 붙혀라

 

topMenu()함수 호출이 완료되면 지역변수인 $selectMenuItem이 사라
져야 하는데 tabMenu()함수 내부의 중첩함수(클로저함수)에서 발생
해 사라지지 않고 계속해서 값을 유지하게 된다.

 

728x90
반응형
LIST

댓글