Lexical Scope, Closure 개념정리

penguin·2022년 2월 21일
0

면접 준비를 하며 javascript 기본개념을 정리해보려 한다. 그 중 가장 이해가 안되던 클로져에 대해 정리해본다.

Lexical Scope

closure에 대해 이해하기 위해선 lexical scope를 이해해야 한다. scope가 변수에 접근할 수 있는 범위라면 lexical scope는 무엇일까?

var x = 1;

function a() {
   var x = 2;
   b();
}

function b() {
  console.log(x);
}

a(); // 1
b(); // 1

위에 코드를 보면 함수 a, b 둘 다 1을 출력하는 것을 볼 수 있다. 함수 a에서 x가 2로 할당되었는데 함수 a를 실행시켰을 때 2가 아닌 1이 출력되는 것을 볼 수 있다.
그 이유는 함수 b가 함수 a 안에서 호출되면서 지역변수 x에 접근하는 것이 아니라 함수 b가 선언되면서 전역변수 x에 접근하기 때문이다.

var num = 100;

function outter() {
  var num = 1;
  function inner() {
    console.log(num)
  }
  inner();
}

outter(); // 1

위에 코드처럼 함수 inner가 함수 outter 안에서 선언되었으면 전역변수 num에 접근하는게 아니라 outter의 지역변수인 num에 접근하게된다.
이렇게 함수가 호출될 때가 아니라 함수가 선언될 때 scope가 정해지는 것을 Lexical scope라고 한다.


Closure

lexical scope를 알아보았으니 이제 closure에 대해 알아보자

function outter() {
  let num = 100;
  return function inner() {
  	console.log(num)
  }
}

let closure = outter();
closure(); // 100

outter 함수 안의 num에 직접적으로 접근할 수는 없지만 closure에 outter 함수의 반환값인 inner 함수를 할당하여 closure를 실행하면 outter 안의 지역변수인 num에 접근할 수 있다. 이렇게 외부함수 밖에서 내부함수가 호출되더라도 외부함수의 지역변수에 접근할 수 있는 함수를 Closure라고 부른다


Closure 활용

Closure를 활용하여 class의 private을 따라할 수 있다.

let counter = (function() {
  let num = 0;
  function add(x) {
    num += x;
  }
  return {
    increament: function() {
      add(1);
    },
    decreament: function() {
      add(-1);
    },
    value: function() {
      return num;
    }
  };
})();

console.log(num); // error
console.log(counter.value()); // 0
counter.increament();
counter.increament();
counter.increament();
console.log(counter.value()); // 3
counter.decreament();
console.log(counter.value()); // 2

위 코드에서 우리는 num과 add에 직접 접근할 수 없지만 closure인 increament, decreament, value를 통해 접근할 수 있다.


참고자료

https://developer.mozilla.org/ko/docs/Web/JavaScript/Closures
https://poiemaweb.com/js-closure

profile
힘내자

0개의 댓글