[JavaScript] 클로져

2022. 7. 12. 14:45WEB/Javascript

MSN 정의 : 함수와 함수가 선언된 어휘적(lexical) 환경의 조합을 말한다. 이때의 환경은 클로저가 생성된 시점의 유효 범위 내에 있는 모든 지역변수로 구성된다.

 

- 클로저 함수란 외부 함수의 컨텍스트에 접근할 수 있는 내부 함수를 뜻한다. : 이 현상이 없으면 클로저라고 할수가 없다. 꼭 외부함수의 컨텍스트에 접근하는 무언가가 있어야 한다.

- 데이터를 보존하는 함수다. : 외부 함수의 실행이 끝나더라도 외부 함수 내의 변수가 메모리에 저장이 된다. (메모리 해제 전까지 할당)

- 현업에서는 코드가 방대하기 때문에 특정 기능에서 다른 부분을 참고 하기보다는 그자체에서 해결하기위해서 클로져를 쓴다.

- Closure는 일급함수로서 전달할 수 있는 함수인데, 함수를 이리 저리 전달해서 사용할 때, 그 함수가 처음 정의될 때의 Context를 그대로 가지고 있을 필요가 있는 경우 사용한다.

 

  function makeAdder(x) {
      var y = 1;
      return function(z) {
        y = 100;
        return x + y + z;
      };
    }

	//x와 y의 환경이 저장됨					
    var add5 = makeAdder(5);
    var add10 = makeAdder(10);
    
    //클로저에 저장된 x,y값에 접근하여 계산
    console.log(add5(2)); // 107 (x:5 + y:100 + z:2)
    console.log(add10(2)); //112 (x:10 + y:100 + z:2)

- 클로저는 makeAdder가 리턴하는 익명의 함수이다

- makeAdder는 클로저를 사용하고 있다 라고 말할수 있음 

 

var a = 0;
function foo() {
    var b = 0;
    return function() {
        console.log(++a, ++b);
    };
}

var f1 = foo();
var f2 = foo();

f1(); // 1,1
f1(); // 2,2 
f2(); // 3,1
f2(); // 4,2

//foo는 한번만 실행되고 실행되었을 때 그때 상태의 변수 b자체를 저장한다. foo가 재실행 되는게 아니므로 재선언이 안된다.

- 외부에서 직접적으로 value에 값을 할당할 수 없으므로 정보의 접근 제한이 가능하다. -> 캡슐화

 

var module = function() {
    
    //은닉될 멤버 정의
	let value = 0;
	function privateMethod(){
    	return value;
        }
    
    
    //공개될 멤버 정의
    return {
    	increase: () =>{
        	value = value +1;
        },
        decrease: function(){
        	value = value -1;
        },
        publicMethod: () => {
        	return privateMethod();
        }
    }
}

let testcase1 = module();
testcase1.increase();
console.log(testcase1.publicMethod());

let testcase2 = module();
testcase2.increase();
testcase2.increase();
testcase2.increase();
console.log(testcase2.publicMethod());

- 클로저를 활용한 모듈 패턴이다.

- 재활용이 가능한 module()함수를 이용하여 인스턴스를 여러개 만들 수 있고 객체의 메소드처럼 호출이 가능하다. public, private한정  자와 비슷하게 사용할 수 있다.

- 클로저를 통해 데이터와 메서드를 같이 묶어서 다룰 수 있다.

- 즉 클로저를 이용하여 객체를 리턴하는 함수를 작성한다면 서로에게 영향을 주지않는 객체들을 만들 수있다.

 

#화살표 함수로 클로저 표현

const lamda1 = x => {
     return y => {
    	return x + y;
    }
}



const lamda2 = x = y => x - y;
}

lamda1(10)(20);
lamda2(10)(5);

 

 

 

# 메모리 해제

- 클로저를 많이 쓰다보면 가비지 컬렉션에 의해 메모리가 해제되지 않는다. 곧 메모리 누수로 이어진다.

- 쓰지않는 시점에서 null이나 undefined를 할당한다. // testcase2 = null;