관리 메뉴

FU11M00N

[ JavaScript ] JS 내부함수,외부함수,Private Variable,클로저 본문

SUA 정보보안/JavaScript

[ JavaScript ] JS 내부함수,외부함수,Private Variable,클로저

호IT 2021. 2. 4. 06:48

 

 

 

 

이미지 출처 :        https://www.inflearn.com/course/javascript-%EC%9E%90%EB%B0%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8-%EA%B0%95%EC%A2%8C#

 

생활코딩의 이고잉 님의 강의를 기반으로 개인 공부용으로 정리한 포스팅입니다.

 

 

 

 

 


 

슬슬 강의가 어려워집니다.. 클로저 이해하느라 2시간걸렸다..

 

 

 

- 내부함수

 

 

자바스크립트는 함수 안에서 또 다른 함수를 선언할 수 있습니다.

 

function outter(){
    function inner(){
        var title = 'test'; 
        console.log(title);
    }
    inner();
}
outter();

 

 

위의 예제에서 함수 outter의 내부에는 함수 inner가 정의 되어 있습니다.

여기서 함수 inner를 내부 함수라고 합니다.

 

내부함수는 외부함수의 지역변수에 접근할 수 있습니다.

 

 

 

function outter(){
    var title = 'test';  
    function inner(){        
        console.log(title);
    }
    inner();
}
outter();

위의예제는 조금 다릅니다.

 

실행시켜보면 아래 그림과 같이 test가 출력되는 것을 확인할 수 있습니다.

 

 

 

내부함수 inner에서 title을 호출했을때

외부함수인 outter의 지역변수에 접근을합니다.

 

 

 

 

- 클로저(closure)란?

 

 

클로저(closure) 내부함수가 외부함수의 맥락(context)에 접근할 수 있는 것을 말합니다.

클로저는 함수를 저장한 레코드(record)이며, 스코프(scope)의 인수(Factor)들은 클로저가 만들어질 때 정의(define)되며, 스코프 내의 영역이 소멸(remove)되었어도 그에 대한 접근(access)은 독립된 복사본인 클로저를 통해 이루어질 수 있습니다.

 

이러한 매커니즘을 클로저라고 합니다.

 

클로저는 자바스크립트를 이용한 고난이도의 테크닉을 구사하는데 필수적인 개념으로 활용되기 때문에

이해하는것이 좋습니다.

 

 

아래 예제는 이전의 예제를 조금 변형한 것입니다.

 

 

function outter(){
    var title = 'test';  
    return function(){        
        console.log(title);
    }
}
inner = outter();
inner();

 

 

 

예제의 실행순서를 주의하면서 보도록 하겠습니다.

 

먼저 7행에서 outter()을 호출합니다. 그 결괏값이 inner에 들어가고 값은 이름이 존재하지않는 함수입니다.

 

일반적으로 프로그래밍을 한번이랃로 배우셨던분들은 이상한점을 느꼈을겁니다.

8행에서 inner()을 호출하면서 outter함수는 실행이 끝났기때문에 소멸해야 정상입니다.

 

하지만 8행에서 함수 inner()을 호출하여 실행하면 출력값은 test입니다.

외부함수의 지역변수 title이 소멸되지않아 출력이되었습니다.

이것이 클로저입니다.

 

즉 클로저는 내부함수가 외부함수의 지역변수에 접근 할 수 있고, 외부함수는 외부함수의 지역변수를 사용하는 내부함수가 소멸될 때까지 소멸되지 않는 특성을 의미합니다.

 

 

 

 

- Private Variable

 

 

Private 속성은 객체의 외부에서는 접근 할 수 없는 외부에 감춰진 속성이나 메소드를 의미합니다.

 

이를 통해서 객체의 내부에서만 사용해야 하는 값이 노출됨으로서 생길 수 있는 오류를 줄일 수 있습니다.

 

 

자바와 같은 언어에서는 이러한 특성을 언어 문법 차원에서 지원하고 있습니다.

 

 

자바에서는 private ~~ 형식으로 변수등을 선언하는 식으로 사용합니다.

 

 

 

 

클로저를 이용해서 영화의 제목을 저장하고 있는 객체를 정의하는 예제를 보겠습니다.

 

 

function factory_movie(title){
    return {
        get_title : function (){
            return title;
        },
        set_title : function(_title){
            title = _title
        }
    }
}
ghost = factory_movie('Ghost in the shell');
matrix = factory_movie('Matrix');
 
console.log(ghost.get_title());
console.log(matrix.get_title());
 
ghost.set_title('공각기동대');
 
console.log(ghost.get_title());
console.log(matrix.get_title());

 

 

위의 예제를 통해서 알 수 있는 것들을 정리해보면 아래와 같습니다.

 

 

클로저는 객체의 메소드에서도 사용가능합니다.

위의 예제에서는 함수의 리턴값을 객체로 반환하고있습니다.

해당 객체는 메소드 get_title과 set_title이있는데,

이 메소드들은 외부함수인 factory_movie의 인자값으로 전달된 지역변수 title을 사용중입니다.

 

또한 동일한 외부함수안 안에서 만들어진 내부함수나 메소드는 외부함수의 지역변수를 공유합니다.

17행의 set_title은 외부함수 factory_moive의 지역변수인 title의 값을 "공각기동대"로 변경했습니다.

19행에서 ghost.get_title();의 값이 '공각기동대'인 것은
set_title와 get_title 함수가 title의 값을 공유하고 있다는 의미입니다.

 

똑같은 외부함수 factory_movie를 공유하고 있는 ghost와 matrix의 get_title의 결과가 서로 다릅니다.

그것은 외부함수가 실행될 때마다 새로운 지역변수를 포함하는 클로저가 생성되기 때문입니다.

따라서 ghost와 matrix는 서로 완전히 독립된 객체가 되는 것 입니다.

 

 

factory_movie의 지역변수 title은 2행에서 정의된 객체의 메소드에서만 접근 할 수 있는 값입니다.

이 말은 title의 값을 읽고 수정 할 수 있는 것은
factory_movie 메소드를 통해서 만들어진 객체 뿐이라는 의미와 같습니다.

JavaScript는 기본적으로 Private한 속성을 지원하지 않는데,
클로저의 이러한 특성을 이용해서 Private한 속성을 사용할 수 있게 되는 것 입니다.

 

 

이 클로저 특성을 응용해서 자주 실수하는 경우도 알아보도록 하겠습니다.

 

 

 

var arr = []
for(var i = 0; i < 5; i++){
    arr[i] = function(){
        return i;
    }
}
for(var index in arr) {
    console.log(arr[index]());
}

 

 

 

 

 

 

위의 예제의 결과 값은 5가 5번출력됩니다.

 

함수가 함수 외부의 컨텍스트에 접근할 수 있을 것으로 기대하겠지만 위의 결과는 아래와 같습니다.

 

 

 

 

 

 

 

var arr = []
for(var i = 0; i < 5; i++){
    arr[i] = function(id) {
        return function(){
            return id;
        }
    }(i);
}
for(var index in arr) {
    console.log(arr[index]());
}

 

 

 

0부터 4까지 출력을할려면 위와같이 코드를 짜야합니다.

 

필자는 위의코드를 이해하느라 2~3시간이 소요했습니다.

처음 개념을 접했기때문. 만약 더욱 자세한 설명이 필요하다면 생활코딩 강의에서 들을수있습니다.

https://www.youtube.com/watch?time_continue=353&v=9A0pMrS6Bh0&feature=emb_logo

 

 

아래는 클로저 개념을 더 잘 이해하기 위한 참고 링크입니다.

 

 

 

 

 

 

SUA 정보보안 멘토링에 참여하고 있습니다.

 

 

Comments