• 회원가입
  • 로그인
  • 구글아이디로 로그인

[Functions] JS - Closure - 클로저 (전역변수/지역변수/카운터)

1.

JS 변수는 크게 (전역변수・지역변수) 2종류 존재.

 

2.

전역변수는 클로저 이용하면 지역변수(개별변수)로 전환 가능.

 

 

지역변수

※ 함수는 함수 안에 정의된 모든 변수에 접근 가능.


<button type="button" onclick="homzzang()">클릭</button>


<p id="demo"></p>


<script>

function homzzang() {

  var a = 3; // 지역변수

  document.getElementById("demo").innerHTML = a * a; // 9

</script>

 

결과보기


[정리] 

 

1.

지역변수는 함수 안에서만 사용 가능.
다른 함수나 스크립트 코드엔 노출 안 됨.

 

2.

전역변수와 이름 같은 경우 있더라도 두 변수는 엄연히 다른 변수임.

즉, 하나를 수정해도 다른 것에 영향 안 미침.

 

 

 

전역변수

 

<button type="button" onclick="homzzang()">클릭</button>


<p id="demo"></p>


<script>

var a = 3;  // 전역변수

function homzzang() {

  document.getElementById("demo").innerHTML = a * a; // 9

</script>

 

결과보기


[정리] 

 

1.

웹페이지에서 전역변수는 window 객체에 속함.

 

2.

전역변수는 웹페이지와 창의 모든 스크립트에서 사용 및 변경 가능.

 

3.

지역볌수와 이름 같은 경우 있더라도, 두 변수는 엄연히 다른 변수임.

즉, 하나를 수정해도 다른 변수엔 영향 안 미침.

 

4.

var 키워드 없이 생성된 변수는 항상 전역변수 임.

설사, 그 변수가 함수 안에서 선언되어도 마찬가지.

 

 

변수 수명

 

1.

전역변수는 애플리케이션 (브라우저창, 웹페이지)이 살아있는 한 유효함.

 

2.

지역변수는 함수 호출 시 생성되서, 함수 종료 시 사라짐.

 

 

카운터 딜레마

아래 예제는 전역변수 사용하므로, 함수 밖의 다른 코드로 인해 전역변수가 변경될 수도 있음.

 

<p id="demo"></p>


<script>

var counter = 0; // 카운터 초기화


function add() { // 카운터 증가 함수

  counter += 1;

}


// add() 함수 3번 호출

add();

add();

add();


document.getElementById("demo").innerHTML = "호출횟수: " + counter; // 3

</script>

 

결과보기


아래 예제는 지역변수와 별도로 전역변수가 존재하여 카운터 정상작동 안 함.


<p id="demo"></p>


<script>

var counter = 0; // 카운터 초기화


function add() { // 카운터 증가 함수

  var counter = 0;

  counter += 1;

}


// add() 함수 3번 호출

add();

add();

add();


document.getElementById("demo").innerHTML = "호출횟수: " + counter; // 0

</script>

 

결과보기


아래 예제는 함수호출할 때마다 지역변수를 재설정하기 때문에 카운터 정상작동 안 함.

 

<button type="button" onclick="homzzang()">Count!</button>


<p id="demo">0</p>


<script>

function add() { // 카운터 증가함수

  var counter = 0;

  counter += 1;

  return counter;

}

function homzzang(){ // 카운터 증가시도

  document.getElementById("demo").innerHTML = add(); // 클릭 시 0에서 1로 바뀜.

}

</script>

 

결과보기

※ JS 내부함수 개념 이용해 카운터 딜레마 해결 가능.

 

중첩함수 (Nested Function)

 

1.

모든 함수는 전역 범위에 접근 가능.  


2.

사실 상, JS 경우 모든 함수가 "상위" 범위에 접근 가능.

 

3.

JS는 내부함수 지원하며, 내부함수는 "상위" 범위에 접근 가능.
즉, 함수 안에 또 다른 함수를 정의해서 사용 가능.

 

4.

아래 예제에서 내부함수 plus()는 외부함수인 add() 함수의 counter 변수에 접근 가능.




<p id="demo">0</p>


<script>

document.getElementById("demo").innerHTML = add(); // 1

function add() {

  var counter = 0;

  function plus() {counter += 1;}

  plus();  

  return counter; 

}

</script>

 

결과보기

 


[정리]

 

1.

외부에서 plus() 함수에 접근가능했다면, 카운터 딜레마 해결할 수 있었을 것임.

 

2.

counter = 0 코드를 단 한 번만 실행할 수 있는 방법을 찾을 필요가 있는데, 클로저 통해 해결 가능.

 

 

 

클로저 (closure)

 

<button type="button" onclick="homzzang()">클릭횟수세기</button>


<p id="demo">0</p>


<script>

var add = (function () {

  var counter = 0;

  return function () {counter += 1; return counter;}

})();


function homzzang(){

  document.getElementById("demo").innerHTML = add();

}

</script>

 

결과보기


 

1.

변수 add에는 자체 호출 함수의 반환값이 지정됨.

 

2.

자체 호출 기능은 오직 한 번만 실행됨. 카운터를 0으로 설정하고, 함수 표현식을 반환.

그 결과, add는 함수가 됨. 

3.

여기서 중요한 사실은, 내부함수가 상위 범위의 counter 변수에 접근 가능하단 사실임.

 

4.

이를 클로저 라고 하며, 함수가 사적변수 (Private Variable) 취할 수있게 함.

사적변수는 외부함수의 소멸한 변수를 계속해서 내부함수가 사적으로 꽁쳐두고 이용하는 변수. 

 

5.

카운터는 익명함수 범위에 의해 보호되며, 오직 add 함수 사용해서만 변경 가능.

 

6.

클로저 (closure) 개념. 
외부함수 실행종료로 외부함수의 지역변수 소멸 후에도
내부함수가 외부함수 범위에 접근해서 계속 소멸한 변수를 사적으로 이용하는 걸 말함.

 


 

<script> 

function outter(){ // 외부함수

    var site = '홈짱닷컴 Homzzang.com';  

    return function(){  // 내부함수

        document.write(site);

    }

}

inner = outter(); // 외부함수 간접호출해 외부함수의 지역변수 소멸.

inner(); // 내부함수가 이미 소멸한 외부함수 변수를 계속 이용.
</script>

 

결과보기

 


 

<script> 

function get_abc(abc){

    return {

        get_abc : function (){

            return abc;

        },

        set_abc : function(_abc){

                abc = _abc

        }

    }

}

a = get_abc('A');

b = get_abc('B');

 

document.write(a.get_abc()); // A

document.write(b.get_abc()); // B

a.set_abc('C'); 

document.write(a.get_abc()); // C

document.write(b.get_abc()); // B
</script>


결과보기

코드 설명 https://opentutorials.org/module/532/6544 참고.

 

PS.

 

function outer() {

    var a = 1;


    function inner() {

        var a = 2;

        console.log(a); // 2

    }

    inner();

}

outer(); // 2

 


 

<script>

var d = "x";


function outer() {

    var a = 1;

    var b = 'B';


    function inner() {

        var a = 2;

        // console.log(a); // 2

        console.log(b); // B

        //console.log(d); // x

    }

    return inner;

}


var someFun = outer();

someFun();

</script>

결과보기

코드종 님 (180622) https://youtu.be/MbYShFxp-j0


방문 감사합니다. (즐겨찾기 등록: Ctrl + D)

분류 제목
Basic JS - Home (JS입문) + Javascript Framework (프레임워크) 종류
Basic JS - Intro (JS소개)
Basic JS - Where To (JS위치) - JS구문 / JS코드위치 / JS사용법 ※ JS외부링크 주의사항
Basic JS - Output (JS출력= JS쓰기) ★★★★★
Basic JS - Syntax (JS구문) ★
Basic JS - Statement (JS구문= JS명령문)
Basic JS - Comment (JS주석)
Basic JS - Variable (JS변수) ★★★★★
Basic JS - Operator (연산자) - JS연산자 ★★★★★
Basic JS - Data Type - 데이터유형 ★★★★★ (= 데이터형식 = 데이터타입 = 데이터종류 = 자료형…
Basic JS - Function - JS함수 ★★★★★ ※ 일반함수 특징 2
Basic JS - Object - JS객체 ★★★★★
Basic JS - Scope - JS유효범위 (= JS접근범위 = 변수 종류) ★★★★★★★★★★
Basic JS - Event - JS이벤트 (= JS코드실행방법) ★★★★★
Basic JS - Strings - JS문자열
Basic JS - String Methods - JS문자열메서드
Basic JS - Number - JS숫자
Basic JS - Number Method - JS숫자메서드
Basic JS - Math 객체 - JS수학객체 (= JS산수객체 = Math객체 = Math Object = 매스 …
Basic JS - Dates - JS날짜
1/67
목록
찾아주셔서 감사합니다. Since 2012