프로그래밍 공부하기

[20201216][이전블로그글]Closure 본문

Web/[JS] Common

[20201216][이전블로그글]Closure

ihl 2020. 12. 17. 12:57

오늘 레슨에서 Closure라는 개념을 새로 배웠다. Java, C#에도 클로저라는 개념이 있었지만 써본 적이 없어서 한 번 정리해보려 한다.


Closure함수와 함수가 선언된 어휘적 환경의 조합이다. 이해하기 쉽게 말하자면 내부함수에서 외부함수의 문맥에 접근할 수 있는 것. 그러한 내부함수를 클로저 함수라 부른다. Scope Chaining에 의해 외부함수의 문맥에 접근하기 때문에 어휘적 환경의 조합이라 부른다. (스코프는 선언할 때 발생하기 때문이다.)

[예시1]

function OuterFn() {
    let num = 123;
    console.log("num(outer)>>" + num);
    function InnerFn() {
      num++;
      console.log("num+1(inner)>>" + num);
    }
    return InnerFn;
}

[결과1]

let callFn = OuterFn(); //num(outer)>>123
callFn(); //num+1(inner)>>124
callFn(); //num+1(inner)>>125

위의 코드를 보면 OuterFn함수 안에 InnerFn 함수가 들어있다. 이는 OuterFn함수 내에 변수를 하나 선언했는데 InnerFn이라는 함수가 할당된 것이라 이해하면 된다.
이 때 1. InnerFn()에서 외부함수에 있는 num 변수에 접근하고 이를 처리하는 것 을 볼 수 있다. 또한 2. 외부함수가 소멸 후(함수가 return되어 종료)에도 내부함수가 외부함수의 num에 접근하여 이를 처리하고 있는 것 을 볼 수 있다.

 

[예시2]

function OuterFn() {
    let num = 123;
    console.log("num(outer)>>" + num);
    function InnerFn() {
      let num = 10;
      console.log("num+1(inner)>>" + num++);
    }
    return InnerFn;
}

[결과2]

let callFn = OuterFn(); //num(inner)>>10
callFn(); //num+1(inner)>>10
callFn(); //num+1(inner)>>10

보통 클로저는 함수 안에 함수가 있어서 외부 함수에서 내부함수를 리턴하는 형태인데, 이러한 형태를 취하더라도 내부 함수가 외부함수의 문맥에 접근하지 않는다면 클로저라 할 수 없다. 따라서 위 코드는 클로저가 아니다.

 


 

그렇다면 이 클로저를 어디에 사용할 수 있는 것일까..

1. 클로저 모듈(Function Factory)

  •  다른 언어의 private 키워드로 캡슐화/은닉화를 구현하는 것 처럼 클로저를 통해 은닉화를 구현할 수 있다.

 [예제3]

function Student(value){
	let _name = value;
	return {
     getName : function (){
         return _name;
     },
     setName : function(value){
         _name = value.trim();
     }
 }
}

[결과3]

let studentB = Student('BBB');
console.log(studentB.getName()); //BBB
studentB.setName(" CCC");
console.log(studentB.getName()); //CCC
  • 외부함수의 문맥에는 내부함수만으로 접근할 수 있다는 원리를 이용
  • 다른 언어로 말하자면 Student클래스가 private _name; 속성을 갖고 이를 getName(), setName() 메소드로만 접근할 수 있는 것처럼 보인다.

2. 커링(Function Factory)

  • n개의 파라미터를 갖는 함수 대신 n개의 함수를 만들어서 각각 파라미터를 받게하는 방식

[예시4]

function PlusFn(x){
	return function(y){
		return x + y;
	}
}

[결과4]

let addFive = PlusFn(5); //x가 5인 함수 생성
let addTen = PlusFn(10) //x가 10인 함수 생성
console.log(PlusFn(1)(2)) //1+2 = 3
console.log(addFive(2)); //5+2 = 7
console.log(addTen(2)); //10+2 = 12
  • 위처럼 외부함수의 x값을 고정시켜 동일한 원리면서 값만 다른 함수를 쉽게 만들 수 있다.
  • 클로저는 함수와 변수가 선언된 상황을 기억하기 떄문에 가능한 것이다.

3. 템플릿

  • 특정 모양을 만드는 템플릿을 만들 수 있다. 사실 템플릿은 위의 커링과 동일한 활용방법이다.

[예시5]

function templateTag(tag){
	let startTag = '<' + tag + '>';
	let endTag = '<' + tag + '/>';
	return function(content){
		return startTag + content + endTag;
	}
}

[결과5]

let h1Tag = templateTag('h1');
h1Tag('h1태그 내용'); //"<h1>h1태그 내용<h1/>"

 


 

클로저를 사용할 때는 주의사항이 있다. 클로저 사용이 끝나면 참조를 제거해야한다는 것이다. 클로저는 함수가 소멸한 후에도 함수가 수행된 상황을 기억하고 있으므로 사용이 다 끝났다면 null을 할당하여 수동으로 제거해주어야 한다.

let addFive = PlusFn(5); 
let number = addFive(3); //사용

addFive = null;

 

 


참고 사이트
https://opentutorials.org/course/743/6544

 

클로저 - 생활코딩

클로저 클로저(closure)는 내부함수가 외부함수의 맥락(context)에 접근할 수 있는 것을 가르킨다. 클로저는 자바스크립트를 이용한 고난이도의 테크닉을 구사하는데 필수적인 개념으로 활용된다.

opentutorials.org

https://hyunseob.github.io/2016/08/30/javascript-closure/

 

JavaScript 클로저(Closure)

클로저란?MDN에서는 클로저를 다음과 같이 정의하고 있다. 클로저는 독립적인 (자유) 변수를 가리키는 함수이다. 또는, 클로저 안에 정의된 함수는 만들어진 환경을 ‘기억한다’. 흔히 함수 내

hyunseob.github.io

developer.mozilla.org/ko/docs/Web/JavaScript/Guide/Closures

 

클로저 - JavaScript | MDN

클로저는 함수와 함수가 선언된 어휘적 환경의 조합이다. 클로저를 이해하려면 자바스크립트가 어떻게 변수의 유효범위를 지정하는지(Lexical scoping)를 먼저 이해해야 한다. 다음을 보자: function i

developer.mozilla.org

 

'Web > [JS] Common' 카테고리의 다른 글

논리연산자 AND, OR의 결과값  (0) 2020.12.31
내장고차함수: filter, map, reduce  (0) 2020.12.22
호이스팅(Hoisting)  (0) 2020.12.17
Assignment과 Shallow Copy와 Deep Copy  (0) 2020.12.17
[20201216][이전블로그글]...arg  (0) 2020.12.17
Comments