티스토리 뷰

난 자바스크립트에서 객체지향이란건 생각해본적도 없다. 하지만 클로저(Closure) 라는 패턴(?)을 이용해 자바(java)에서 쓰이는 클래스개념을 만들 수가 있다. 그렇다고 자바처럼 단순히 멤버변수와 메소드를 정의만 하는 쉬운방법으로는 되지 않는다. 우선 Closure 가 무엇인지 알기전에 내장함수(inner function)에 대해 알아보자

function outer(num1) {

	var num2 = 5;
    
    function inner() {
        return num1 * num2;
    }
    return inner();
}

함수안에 함수가 있다. 그래서 내장함수이다. 내부함수 inner는 외부함수 outer의 파라메터 num1 과 지역변수 num2 에 접근이 가능하다는 것만 알아두자. 결과값은 어떻게 알아볼 수 있을까.

var result = outer(7);
console.log(result);		// returns 35 (=7x5)
result = outer(8);
console.log(result);		// returns 40 (=8x5)

outer 함수를 호출할 때마다 num1, num2 의 변수가 생성되고 사용되지만, 함수안의 지역변수이므로 계산값을 리턴하고 나면 더이상 쓸모없는 변수가 되어 둘다 GC(가비지컬렉터)의 수거 대상이 된다. 한마디로 outer(7) 같이 호출하고 난 후에는 num1, num2 변수는 없어진다는 이야기이다. 이것을 유념하고 넘어가자.




이제 Closure 예제를 보자. 내장함수와 같은 맥락이지만 조금 다르다.

function outer(num1) {
    
    function inner(num2) {
        return num1 * num2;
    }
    return inner;
}

위의 내장함수 예제와 모가 다르지.. 라고 생각할 수도 있지만 함수 호출의 결과값을 리턴하는 것이 아니라 함수를 리턴하는 것이 다르다. 내부함수를 리턴하고 있는데 그러면 내부함수에서 참조하는 저 num1 변수의 저장값은 계속 살아있을까 GC에 의해 수거되서 없어지는 값일까. 결론은 내부함수 inner 는 outer 함수의 num1 변수를 참조하고 있기 때문에, 사라지면 안되는 값이 되어버린다. 


실행하는 코드로 명확히 알아보자.

var x = outer(7);
var y = outer(8);

// (...중간로직...)

console.log(x(2));		// returns 14 (=7x2)
console.log(y(3));		// returns 24 (=8x3)


보통 outer(7) 같이 함수를 호출하고 나면, 지역변수들은 변수의 범위를 다하기 때문에 없어져야 하지만, 6~7라인에서 리턴된 함수를 가지고 출력을 할 때 보면 각 리턴된 내부함수에 외부함수의 변수들을 참조하여 계산하고 있는 것을 볼 수 있다.


1. 내부함수의 결과값이 아닌 내부함수 자체를 리턴하고 있다.

2. 그 리턴된 내부함수는 외부함수의 파라메터 및 변수들에 접근가능하며 그 값들을 참조하여 가지고 있다.


라는 게 클로저(Closure)의 핵심이다. 


어려움 없이 이해를 했다면 조금 더 복잡한 Closure 를 알아보자.

var createPet = function(name) {
  var sex;
   
  return {
    setName: function(newName) {
      name = newName;
    },
     
    getName: function() {
      return name;
    },
     
    getSex: function() {
      return sex;
    },
     
    setSex: function(newSex) {
      if(typeof newSex == "string" && 
			(newSex.toLowerCase() == "male" || newSex.toLowerCase() == "female")) {
        sex = newSex;
      }
    }
  }
}
 
var pet = createPet("Vivie");
pet.getName();                  // Vivie
 
pet.setName("Oliver");
pet.setSex("male");
pet.getSex();                   // male
pet.getName();                  // Oliver

createPet 이라는 함수가 있다. 문법이 좀 어려워 보이지만, 단순하게 보면 이 함수는 Object 를 리턴하는 함수일 뿐이다. { } 로 묶여 있는 것을 리턴하기 때문이다. 그 Object 안에는 4가지의 property 가 있는데(setName, getName, getSex, setSex), 모두 함수로 정의되있다. 이것들은 외부함수 변수인 name과 sex를 참조하고 있으며, 이 값들을 변경하고 출력할 수 있는 기능(set, get)을 제공하고 있는 것이다. new 연산자만 없지 사실 java에서 객체를 만들고 메소드를 호출하는 것 처럼 보인다.


(출처 : https://developer.mozilla.org/en-US/docs/JavaScript/Guide/Functions)

반응형
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/04   »
1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30
글 보관함