티스토리 뷰

JavaScript

Closure

song 2021. 11. 9. 13:51

Lexical scope (static scope)

function makeFunc() {
	var name = "Hello";
    function displayName() {
    	console.log(name);
    }
    displayName();
}

makeFunc();

위의 코드는 자연스럽게 "Hello"가 출력됨을 예상할 수 있다. Javascript는 lexical scope(선언된 위치를 기준(compile time)으로 scope를 정함, 상대되는 개념으로 호출된 시점(run time)을 기준으로 scope를 정하는 dynamic scope가 있다.)를 사용하여 내부 함수에서 외부함수의 변수에 접근할 수 있기 때문이다.

 

Closure

function makeFunc() {
    var name = "Hello";
    function displayName() {
    	console.log(name);
    }
    return displayName;
}

var myFunc = makeFunc();
myFunc();

 

하지만 위와 같은 코드는 직관적으로 작동하는지 판단하기 어렵다. 몇몇 프로그래밍 언어에서는 함수 안의 지역변수는 그 함수가 처리되는 동안에만 존재하기 때문이다. displayName()을 return하고 나면 name에 더이상 접근할 수 없을 것으로 생각하는 것이 일반적이다.

 

그러나 Javascript의 경우에는 다르다. return 하는 함수가 closure를 형성하기 때문이다. 클로저는 함수와 함수의 lexical scope 환경의 조합이다. 이 환경은 클로저가 생성된 시점의 lexical scope에 있는 모든 변수로 구성된다. 즉, 클로저란 외부 함수의 호출(실행) 여부와 상관 없이 변수, 함수 등에 접근할 수 있는 함수이다. 따라서 위의 예에서 myFunc는 클로저이고 makeFunc()의 내부가 아니더라도 lexical scope에 있는 name에 접근할 수 있는 것이다.

 

Closure example

    var makeCounter = function() {
      var privateCounter = 0;
      function changeBy(val) {
        privateCounter += val;
      }
      return {
        increment: function() {
          changeBy(1);
        },
        decrement: function() {
          changeBy(-1);
        },
        value: function() {
          return privateCounter;
        }
      }
    };

    var counter1 = makeCounter();
    var counter2 = makeCounter();
    alert(counter1.value()); /* 0 */
    counter1.increment();
    counter1.increment();
    alert(counter1.value()); /* 2 */
    counter1.decrement();
    alert(counter1.value()); /* 1 */
    alert(counter2.value()); /* 0 */

클로저를 사용하면 private 변수 및 함수를 구현할 수 있다.

(return에서 각 key에 해당하는 function() 이 선언될 때 closure(함수의 [[scopes]] property)가 형성되고 이는 makeCounter function의 execution context의 scope chain이 된다.)

'JavaScript' 카테고리의 다른 글

Execution context, scope chain  (0) 2022.08.01
keys, getOwnPropertyNames, for...in  (0) 2022.08.01
this binding  (0) 2021.11.09
prototype vs __proto__  (0) 2021.10.06
ECMA?  (0) 2021.07.12
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
TAG
more
«   2026/01   »
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 31
글 보관함