클로저

fe_sw·2022년 7월 30일
0

Javascript

목록 보기
5/22
post-thumbnail

클로저

외부함수에서 자신이 선었됬을떄의 (lexical environment)을 기억해 외부함수의 scope에 접근할 수 있는것을 말한다.자바스크립트에서 클로저는 함수가 생성될때마다 생성된다.

var base = 'Hello, ';

function sayHelloTo(name) { //외부함수
  var text = base + name;
  return function() { //자기자신 함수 
    console.log(text);
  };
}

var hello1 = sayHelloTo('승민');
var hello2 = sayHelloTo('현섭');
var hello3 = sayHelloTo('유근');
hello1(); // 'Hello, 승민'
hello2(); // 'Hello, 현섭'
hello3(); // 'Hello, 유근'

출력된 결과를 보면 text 변수가 동적으로 변화하고 있는 것처럼 보인다. 
실제로는 text라는 변수 자체가 여러 번 생성된 것이다., hello1()hello2(), hello3()은 서로 다른 환경을 가지고 있다

힘수의 실행 컨텍스트가 생성될 때 ,함수의 lexical environment도 생성된다.
이 실행컨텍스트의 lexical environment에는 함수의 지역변수의 정보, 이 함수의 상위 스코프의 대한 정보가 들어있다.

외부함수의 생명 주기가 종료되더라도 내부함수가 선언되었을때의 렉시컬 환경을 기억해 외부함수의 스코프에 접근할 수 있기 떄문이다,

클로저가 필요한 이유

클로저는 상태(state)를 안전하게 변경하고 유지하기 위해 사용한다.

상태가 의도치 않게 변경되지 않도록 상태를 안전하게 은닉(information hiding)하고,
특정 함수에게만 상태변경을 허용하기 위해 사용한다.


전역변수를 줄일 수 있다

전역변수가 많으면 어디에서든 실수로라도 접근을 할 수 있기 때문에 최대한 전역변수를 줄여서 코드를 해야합니다.

클로저 함수는 외부 함수의 실행이 끝나더라도 외부 함수 내 변수를 사용할 수 있다.
클로저는 이처럼 특정 데이터를 스코프 안에 가두어 둔 채로 계속 사용할 수 있게하는 폐쇄성을 갖는다

const btn = document.querySelector('button')

btn.addEventListener('click',handleClick())

function handleCilck(){
  let count = 0
  return function (){
    count++
    return count
  }
}

코드의 재활용

클로저 함수를 각각의 변수에 할당하면 각자 독립적으로 값을 사용하고 보존할 수 있다.
이와 같이 함수의 재사용성을 극대화로 함수 하나를 독립적인 부품의 형태로 분리하는 것을 모듈화라고한다.

클로저를 통해 데이터와 메소드를 묶어다닐 수 있기에 클로저는 모듈화에 유리하다

const newTag = function(open, close) {
    return function(content) {
        return open + content + close
    }
}

const bold = newTag('<b>', '</b>')
const italic = newTag('<i>', '</i>')

console.log(bold(italic("This is my content!"))) //<b><i>This is my content!</i></b>
값을 확인할 수 있고 변경도 할 수 있다

캡슐화 은닉화

캡슐화를 통한 은닉화로 정보의 접근을 제한할 수 있다.

const myObj = {
  count: 0,
  up() {
    this.count++;
    console.log(this.count);
  },
};

myObj.up(); // 1
myObj.up(); // 2
myObj.up(); // 3
myObj.count = 0;
myObj.up(); // 1

up을 호출할 때마다 숫자가 올라가는 것을 확인할 수 있다.
하지만 객체 내부 프로퍼티인 count에 직접 접근하여 숫자를 임의로 변경시킬 수 있다.

만약 악의적인 코드나 실수로 외부에서 내부 프로퍼티를 조작하면 프로젝트에 손상을 줄 수도 있는 것이다.

function counter() {
  let count = 0;
  return {
    up() {
      count++;
      console.log(count);
    },
  };
}

const myCount1 = counter();

myCount1.up(); // 1
myCount1.up(); // 2
myCount1.up(); // 3
myCount1.count = 0;
myCount1.up(); // 4

myCount1.count = 0; 으로 새로운 프로퍼티를 추가하였다.
하지만 up메서드는 기존에 참조하던 외부환경의 count를 여전히 사용하여 원하는 결과를 출력하는 것을 볼 수 있다.

단점

가비지콜렉터에 정리 대상이 되어야 할 것들이 메모리 상에 남아 있게 되므로, 남발 시 비효율적인 메모리 사용을 하게 된다.

0개의 댓글