[ JavaScript ] 자바스크립트 기본 문법 | 내장 함수 & 클로저 개념| Private Variable

2021. 2. 3. 22:53·Archive/Develop
728x90
반응형

이미지 출처 :  https://commons.wikimedia.org/wiki/File:JavaScript-logo.png


 

 

 

해당 포스팅은 생활코딩의 이고잉 님의 강의를 기반으로 개인 공부용으로 정리한 포스팅임을 미리 알립니다.

 

 

 


 

 

 

자바스크립트 기본 문법  ::  내부함수

 

 

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

 

예시로 살펴보는 것이 더 쉬워요.

 

 

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을 호출(4행)했을 때

외부함수인 outter의 지역변수에 접근할 수 있음을 보여줍니다.

 

 

 

 

자바스크립트 기본 문법  ::  클로저(closure)란?

 

 

 

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

 

 

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

알아두는 것이 좋습니다.

 

위에서 언급했던 것과 같이 내부함수는 외부함수의 지역변수에 접근 할 수 있는데,

외부함수의 실행이 끝나서 외부함수가 소멸된 이후에도

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

 

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

 

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

 

 

 

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

 

 

 

 

 

 

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

 

 

7행에서 함수 outter를 호출하고 있습니다.

 

그 결과가 변수 inner에 담기고, 그 결과는 이름이 없는 함수입니다.

 

실행이 8행으로 넘어오면 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_movie의 지역변수인 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]());
}

 

 

위의 예제의 결과 값이 어떻게 될까요?

 

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

 

 

 

 

 

 

 

 

0부터 4까지 정상적으로 출력하고 싶다면, 아래 예제와 같이 코드를 작성해야합니다.

 

 

 

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]());
}

 

 

 

 

 

 

사실 이 클로저라는 개념이 개발을 이제 막 시작하신 분들에게는

복잡하고 어려워 보일 수 있지만,

 

초급 개발자를 벗어난 중급, 더 나아가 고급까지 가실 분들은 반드시 알고 가야할 개념이기도 합니다.

 

 

 

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

 

 

 

  • https://developer.mozilla.org/ko/docs/JavaScript/Guide/Closures
  • http://ejohn.org/apps/learn/#48
  • http://blog.javarouka.me/2012/01/javascripts-closure.html

 

 

 

 

 

 

 

 

728x90
반응형

'Archive > Develop' 카테고리의 다른 글

[ JavaScript ] 자바스크립트 기본 문법 | 함수의 호출(apply)  (0) 2021.02.04
[ JavaScript ] 자바스크립트 기본 문법 | 자바스크립트 arguments | function length  (0) 2021.02.03
[ JavaScript ] 자바스크립트 콜백 & 비동기처리  (0) 2021.02.03
[ JavaScript ] 자바스크립트 함수 지향 | 메소드와 함수 차이 | 함수 리턴값 | 함수 배열  (0) 2021.02.03
[ JavaScript ] 자바스크립트 전역변수와 지역변수 | 변수의 유효범위  (0) 2021.02.03
'Archive/Develop' 카테고리의 다른 글
  • [ JavaScript ] 자바스크립트 기본 문법 | 함수의 호출(apply)
  • [ JavaScript ] 자바스크립트 기본 문법 | 자바스크립트 arguments | function length
  • [ JavaScript ] 자바스크립트 콜백 & 비동기처리
  • [ JavaScript ] 자바스크립트 함수 지향 | 메소드와 함수 차이 | 함수 리턴값 | 함수 배열
코뮤(commu)
코뮤(commu)
코딩으로 커뮤니케이션하는 코뮤입니다 😎
  • 코뮤(commu)
    코뮤(COMMU)
    코뮤(commu)
  • 전체
    오늘
    어제
    • 분류 전체보기
      • Archive
        • Hacking
        • Develop
        • ETC
      • Algorithm
      • DB&Infra
      • ETC
      • Node
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

    • IT지식보따리
    • IT가 맛있다
    • IT 천재
  • 공지사항

    • 배고픕니다
  • 인기 글

  • 태그

    백준 파이썬
    파이썬 기초 문제
    자바스크립트
    코드업
    oracle db
    비박스
    파이썬 문제
    코드업 파이썬 기초 100제
    장고
    파이썬 알고리즘
    파이썬 기초
    Django
    Git
    자바스크립트 객체
    파이썬 백준
    javascript
    docker
    백준 풀이
    파이썬
    코드업 기초
    자바스크립트 API
    보안뉴스
    백준
    백준 문제풀이
    Codeup
    Oracle
    C++
    카카오 100일 프로젝트
    Python
    오라클
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.1
코뮤(commu)
[ JavaScript ] 자바스크립트 기본 문법 | 내장 함수 & 클로저 개념| Private Variable
상단으로

티스토리툴바