본문 바로가기

Development/Web & Server

[Javascript] closure란...

Closure란

- 함수와 함수가 만들어진 환경으로 이루어진 오브젝트이다. 

(여기서 만들어진 환경은 함수가 만들어질때 사용할 수 있었던 변수들로 이루어진다.)


function makeFunc() { 

var name = "Mozilla"

function displayName() { 

alert(name); 

}

return displayName; 

var myFunc = makeFunc(); 

myFunc();


여기서 myFunc이 클로져 함수를 가지고 있다.


다양한 예제를 살펴보자~!


예제 1.

function makeAdder(x) {

  return function(y) {

    return x + y;

  };

}


var add5 = makeAdder(5);

var add10 = makeAdder(10);


print(add5(2));  // 7

print(add10(2)); // 12



예제 2.

function makeSizer(size) {

  return function() {

    document.body.style.fontSize = size + 'px';

  };

}


var size12 = makeSizer(12);

var size14 = makeSizer(14);

var size16 = makeSizer(16);



예제 3. (모듈 패턴이라고 알려짐)


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 */


실수하기 쉬운 것들..


function showHelp(help) {

  document.getElementById('help').innerHTML = help;

}


function setupHelp() {

  var helpText = [

      {'id': 'email', 'help': 'Your e-mail address'},

      {'id': 'name', 'help': 'Your full name'},

      {'id': 'age', 'help': 'Your age (you must be over 16)'}

    ];


  for (var i = 0; i < helpText.length; i++) {

    var item = helpText[i];

    document.getElementById(item.id).onfocus = function() {

      showHelp(item.help);

    }

  }

}


setupHelp();


위의 구문에서 문제점은 for문에서 item부분의 변수이다. 현재 배열의 갯수가 3개이므로 3개의 클로져가 하나의 item 변수를 공유하기 때문에 문제 발생~! 해결하기 위해서는 함수를 통해 새로운 환경을 만들어주자.


  function showHelp(help) {

  document.getElementById('help').innerHTML = help;

}


function makeHelpCallback(help) {

  return function() {

    showHelp(help);

  };

}


function setupHelp() {

  var helpText = [

      {'id': 'email', 'help': 'Your e-mail address'},

      {'id': 'name', 'help': 'Your full name'},

      {'id': 'age', 'help': 'Your age (you must be over 16)'}

    ];


  for (var i = 0; i < helpText.length; i++) {

    var item = helpText[i];

    document.getElementById(item.id).onfocus = makeHelpCallback(item.help);

  }

}


setupHelp();