자바 스크립트 Closure

김종현·2023년 3월 15일
0

Js

목록 보기
12/16

Closure

선요약
-Js의 클로저는 함수의 일급 객체 성질을 이용한다.
-함수가 생성도리 때 함수 내부에서 사용되는 변수들이 외부에 존재하는 경우 그 변수들은 함수의 스코프에 저장된다.
-함수와 함수가 사용하는 변수들을 저장한 공간을 클로저라고 한다.
-별도의 선언 없이 외부 변수 묶어서 계산.

일급 객체 first-class object

-자바스크립트에서 함수는 일급 객체다. 따라서 함수는 변수처럼 다룰 수 있다.
-일급 객체의 조건

  • 다른 함수에 매개변수로 제공할 수 있다
  • 함수에서 반환 가능하다(함수가 함수를 반환)
  • 변수에 할당 가능하다
//함수를 다른 함수의 인자로 넘길 수 있다.
function add(a,b){
  return a+b
}

[1, 2, 3].reduce(add, 0)
// 익명 함수를 생성할 수 있다.
(() => {
  console.log('땃쥐')
})()

//중첩 함수를 생성할 수 있다.
function outer(a){
  function inner(b){
    return a+b
  } 
  return inner(10)
}

const Person = (name) => {
  // 함수를 변수로 생성(여기선 내부에) *이 부분이 굉장히 중요, closure 이해에 중요함.
  const printName = () => console.log(name)
  return {printName}
} // 함수를 리턴하며 closure를 생성

const person = Person('Kim')
person.printName()

function printName(name){
  console.log('name : ', name)
}

// 함수끼리 비교
// === 의 경우, 변수가 같은 객체(함수)를 가리키는지 체크한다.
console.log(printName === person.printName)

함수 생성해서 리턴하는 함수 = 팩토리 함수.
팩토리 함수 내부의 변수들은 팩토리 함수가 끝나고 메모리에 여전히 존재한다.

예시 1)

function createCard(){
  let title = "";
  let constent = "";
  function changeTitle(text){title = text}
  function changeContent(text){content = text}
  function print(){
    console.log("TITLE - ", title);
    console.log("CONTENT - ", content);
  }
  return { changeTitle, changeContent, print};
  // 꼭 객체로 return 할 필요 없이 하나의 함수로 리턴해도 됨.
}

const card1 = createCard(); // card1변수에 createCard를 할당해 클로저 생성
card1.changeTitle("생일카드");
card1.changeContent("생일축하");
card1.print();

const card2 = createCard(); // card2변수에 createCard를 할당해 클로저 생성
							// card1과는 다른 메모리 공간에 할당.
card2.changeTitle("감사카드");
card2.changeContent("고마워");
card2.print();

예시 2)

let rate = 1.05;

function app(){
  let base = 10;
  
  return function (price) {
    return price * rate + base;
  };
}

const getPrice = app();
getPrice(120) // 136
// base는 app 함수 내부, rate는 외부의 스코프에 존재한다.
// 함수가 참조하는 변수는 실행 시점에 실행 컨텍스트에 의해 스코프가 결정된다.

console.log(app()(1)); // 11.05
rate = 1.1;
console.log(app()(1)); // 11.1
// 스코프에 따라서 변수에 영향을 받는다.
// rate의 변경은 두 클로저 함수 호출에 반영되지만, base는 증가해도 영향을 미치지 않는다. 왜냐면 내부적으로 해당 값이 계산되어 있기 때문.
// base는 app 호출 시 매번 생성되는 반면, rate는 매번 생성되지 않는다.

사용 이유

-상태를 안전하게 은닉하고 보존시키기 위함, 특정 함수한테만 클로저를 수정하는 권한을 부여.
-다수의 개발자와 함께 일을 할 때 실수를 방지하고 더 탄탄한 코드를 만들기위한 코드 패턴

function createCard() {
    let title= "";
    let content= "";
    
    function changeTitle(text) {
      title= text
    }
    
    function changeContent(text) {
      content= text
    }
    
    function print() {
      console.log("TITLE -", title);
      console.log("CONTENT -", content);
    } 

    return { changeTitle, changeContent, print};
}
  • createCard 함수 본문에 있는 title, content 변수는 외부에서 접근할 수 없게 된다.
  • 따라서 changeTitle, changeContent 함수를 통해 수정할 수 있도록 지정한다.
  • 값을 읽을 수 있도록 제공하는 함수는 print로 지정.
  • 그리고 이 모든 함수를 객체로 묶어서 createCard 함수에서 return,
  • const myCard = createCard()와 같은 형태로 인스턴스를 만들어서 사용할 수 있다.

일종의 템플릿인가?

클로져 Closure

let posion = 3;

function add2(a,b){
const c = a+b+poison;
return c;}

add2(6,11); // 20.
profile
나는 나의 섬이다.

0개의 댓글