Home Closure 클로저
Post
Cancel

Closure 클로저

Closure


  • 외부 함수 안에 있는 내부 함수.
  • 내부 함수가 외부 함수에 접근할 수 있는 것을 클로저라 한다.
  • 클로저 함수 안에서는 지역변수(innerVar) 외부 함수의 변수(outerVar) 전역변수(glovalVar)의 접근이 전부 가능하다.
  • 함수가 본인이 생성된 주변 환경을 지속적으로 기억하는것을 의미한다.
  • 함수가 실행되는 위치가 어디인지 관계가 없다.

ex1)


1
2
3
4
5
6
7
8
9
10
11
12
13
function add () {
   var str1 = 'hello';
   var str2 = 'world';

   function strAdd () {
      console.log(str1 + ' ' +str2);
   }

   return strAdd;
}

var a = add();
a(); // "hello world"

함수가 생성된 주변 환경을 지속적으로 기억하기 때문에 str1str2 변수에 접근할수 있게 되면서 콘솔에 ‘hello world’를 찍게 된다.

ex4) ( 커링 )


1
2
3
4
5
6
7
8
9
10
11
function makeAdder (x) {
   return function add (y) {
      return x + y;
   }
}

var addFive = makeAdder(5);
var addTen = makeAdder(10);

addTen(2); // 7
addFive(1); // 11

풀이


var addFivemakeAdder(5); 을 할당한것은 function add (y) { return 5 + y; }이 되고 var addTenmakeAdder(10);을 할당한것은 function add (y) { return 5 + y; }된다.

addTen(2); 을 실행하면 새로운 makeAdder Scope가 생기고 콘솔에 7이 찍히고 addFive(1);을 실행하면 또 새로운 makeAdder Scope가 생기고 콘솔에 11이 찍히게 된다.

클로저 모듈 패턴


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
function makeCounter() {
   let privateCounter = 0;
    return {
      increment: function() {
         privateCounter++;
      },
      decrement: function() {
         privateCounter--;
      },
      getValue: function() {
         return privateCounter;
      }
   }
}

// let obj = {} return obj와 같다.

let counter1 = makeCounter();
counter1.increment();
counter1.increment();
counter1.getValue(); // 2


let counter2 = makeCounter();
counter2.increment();
counter2.decrement();
counter2.increment();
counter2.getValue(); //1
  • 객체의 key의 값이 함수일 때 메소드이다.
  • 변수를 스코프 안쪽에 가두어 함수 밖으로 노출시키지 않는 방법.
  • counter1, counter2 두 카운터에 각기 다른 privateCounter를 다루면서 PrivateCounter를 밖으로 노출시키지 않는다.

이를 통해서 객체의 내부에서만 사용해야 하는 값이 노출됨으로서 생길 수 있는 오류를 줄일 수 있다.

for loop closure


closure example


1
2
3
4
5
for (var i = 1; i < 6; i++) {
  setTimeout(function () {
    console.log(i);
  }, i * 1000);
}
1
2
3
4
5
6
시간 로그
1초	1
2초	2
3초	3
4초	4
5초	5

클로저

1
2
3
4
5
6
7
8
9
10
11
function test () {
   for (var i = 1; i < 6; i++) {
      (function(ct) {
         setTimeout(function () {
            console.log(ct);
         }, ct * 1000);
      })(i);
   }
}

test();

블록 스코프 let 사용

1
2
3
4
5
for (let i = 1; i < 6; i++) {
  setTimeout(function () {
    console.log(i);
  }, i * 1000);
}
This post is licensed under CC BY 4.0 by the author.