songin.dev님의 블로그

자바스크립트 클로저 본문

Developer/Langauge

자바스크립트 클로저

songin.dev 2022. 7. 19. 11:23
728x90

클로저

function outerFunc() {
  var x = 10;
  var innerFunc = function() { console.log(x); }
  return innerFunc;
}

var inner = outerFunc();
inner(); // 10

outerFunc 실행 컨텍스트는 사라졌지만, outerFunc 변수 객체는 여전히 남아있고, innerFunc의 스코프 체인으로 참조되고 있다.

이것이 자바스크립트에서 구현한 클로저라는 개념이다.

이미 생명 주기가 끝난 외부 함수의 변수를 참조하는 함수를 클로저라고 한다.

 

function outerFunc(arg1, arg2) {
  var local = 8;
  function innerFunc(innerArg) {
    console.log((arg + arg2) / (innerArg + local));
  }
  return innerFunc;
}
var exam1 = outerFunc(2, 4);
exam1(2); // 0.6

outerFunc()가 실행되면서 생성되는 변수 객체가 스코프 체인에 들어가게 되고,

이 스코프 체인은 innerFunc()의 스코프 체인으로 참조된다.

 

클로저의 활용

클로저는 성능적인 면과 자원적인 면에서 약간 손해를 볼 수 있으므로 무차별적으로 사용해서는 안 된다.

 

특정 함수에 사용자가 정의한 객체의 메서드 연결하기

function HelloFunc() {
  this.greeting = "hello";
}

HelloFunc.prototype.call = function(func) {
  func ? func(this.greeting) : this.func(this.greeting);
}

var userFunc = function(greeting) {
  console.log(greeting);
}

var objHello = new HelloFunc();
objHello.func = userFunc;
objHello.call();

함수의 캡슐화

var buffAr = [
    'I am ',
    '',
    '. I live in ',
    '',
    '. I\'am ',
    '',
    ' years old.',
];

function getCompletedStr(name, city, age) {
    buffAr[1] = name;
    buffAr[3] = city;
    buffAr[5] = age;

    return buffAr.join('');
}

var str = getCompletedStr('zzoon', 'seoul', 16);
console.log(str);

문자 템플릿을 전역 변수에 저장하고, 사용자의 입력을 받은 후 이 전역 변수에 접근하여 완성된 문자를 출력하는 방식으로 함수를 작성한 것이다.

단점은 buffAr이라는 배열은 전역 변수로서, 외부에 노출되어 있다는 점이다.

이는 다른 함수에서 이 배열에 쉽게 접근하여 값을 바꿀 수도 있고, 실수로 같은 이름의 변수를 만들어 버그가 생길 수도 있다.

하지만, 클로저를 활용하여 buffAr을 추가적인 스코프에 넣고 사용하게 되면, 이 문제를 해결할 수 있다.

var getCompletedStr = (function() {
  var buffAr = [
    'I am ',
    '',
    '. I live in ',
    '',
    '. I\'am ',
    '',
    ' years old.',
  ];
  return (function(name, city, age) {
    buffAr[1] = name;
    buffAr[3] = city;
    buffAr[5] = age;
    
    return buffAr.join('');
  });
})();

var str = getCompletedStr('zzoon', 'seoul', 16);
console.log(str);

getCompletedStr에 익명의 함수를 즉시 실행시켜 반환되는 함수를 할당한다.

이 반환되는 함수가 클로저가 되고, 이 클로저는 자유변수 buffAr을 스코프 체인에서 참조할 수 있다.

 

- 본 포스팅은 "인사이드 자바스크립트" 도서를 기반으로 작성한 글입니다.

반응형
Comments