FEDev Story

자기실행 익명함수를 활용한 모듈패턴 본문

Javascript/★★★

자기실행 익명함수를 활용한 모듈패턴

지구별72 2016. 4. 4. 15:14

자기 실행 익명 함수

(function(){
    var private_var = "private";
})();

//변수 private_var이 선언되지 않았다는 에러가 출력된다.
console.log(private_var);

위의 함수는 함수명을 지정하거나 함수를 변수에 저장하지도 않고 함수를 바로 실행하기 때문에 자기 실행 익명 함수라고 한다. 자기 실행 익명 함수는 변수 스코프를 제어하는 데 사용하며, 변수가 코드 외부로 노출되지 않게 해준다. 이런 이유로 자바스크립트 플러그인 개발할 때 유용하게 활용할 수 있다.

변수 덮어쓰기를 차단해야 하는 사례로 흔히 제이쿼리와 프로토타입 자바스크립트 라이브러리를 모두 사용하는 경우 두 라이브러리 모두 단일 문자 변수 $를 폭넓게 활용하고 있다. 다음 코드처럼 $ 파라미터를 사용하는 자기 실행 익명 함수로 jQuery 변수를 전달하면 함수 내에서 $가 프로토타입 라이브러리에 의해 바뀌는 것을 방지할 수 있다.

(function( $ ){
    console.log( $ );
})( jQuery );

모듈 패턴 - 자바스크립트에서의 private 변수 활용

var picture = (function(){
      var movie_title = 'Batman v Superman',
            score = '7.33';

      return {
           movie : movie_title + ' - ' + score,
           rating : score
      };
})(); 
// 'Batman v Superman - 7.33' 이 출력
console.log(picture.movie);
// '7.33' 출력
console.log(picture.rating);

//undefined가 출력
console.log(picture.score);

picture.score = '8.50';
//위에서 추가한 score 속성값인 '8.50'을 출력
console.log(picture.score);

//여전히 'Batman v Superman - 7.33'을 출력
console.log(picture.movie);

위 예제에서 자기 실행 익명 함수는 즉시 실행되고 movie와 rating을 속성으로 가진 객체를 반환하여 picture변수에 저장한다. 이렇게 하면 전역 스코프에 movie_title과 score을 추가하는 대신 변수 picture만 추가할 수 있다.

그러나 한가지 문제점은 자기 실행 익명 함수가 실행을 마치면 자기 실행 익명 함수에서 정의된 변수 movie_title과 score는 사라지므로 이들 변수를 바꿀 수 없다는 점이다. movie_title과 score는 picture 변수에 저장된 객체의 속성이 아니므로 picture 객체로 접근할 수 없다. 이들 변수는 익명함수가 반환하는 객체의 movie와 rating 속성을 정의하는데 사용하는 변수다. 이들 속성은 익명 함수가 실행될 때 한 번만 설정되고 그 후로는 수정되지 않았다. 위 예제에서 picture.score는 변수 picture가 객체이므로 객체에 새로운 속성 score를 추가할 수 있다. 그런 이유로 picture.movie 속성이 변하지 않는 이유다.

이들 값을 수정하려면 매번 호출할 때마다 속성에 접근하게끔 속성을 메서드로 바꿔야 한다.

var picture = (function(){
      var movie_title = 'Batman v Superman',
            score = '7.33';

      return {
           movie : function(){
                  return movie_title + ' - ' + score;
           },
           setRating : function(number){
                  score = number;
           }
      };
})(); 

// 'Batman v Superman - 7.33' 이 출력
console.log(picture.movie());

picture.setRating('8.50');
//'Batman v Superman - 8.50'을 출력
console.log(picture.movie());

이렇게 하면 자기 실행 익명 함수가 실행을 마치더라도 movie 메서드와 setRating 메서드를 이용해 변수 movie_title과 score에 계속 접근 할 수 있다. 이제 변수 movie_title과 score는 picture 객체의 private 속성처럼 동작한다. 이들 변수는 익명 함수가 반환하는 객체의 메서드를 이용해서만 접근할 수 있고, 객체나 객체의 프로토타입으로 직접 접근할 수는 없다.
 
Comments