Closure

  • ์™ธ๋ถ€ ํ•จ์ˆ˜์˜ ๋ณ€์ˆ˜์— ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๋Š” ๋‚ด๋ถ€์˜ ํ•จ์ˆ˜๋ฅผ closure ๋ผ๊ณ  ํ•ฉ๋‹ˆ๋‹ค. closure๋Š” ์ง€์—ญ ๋ณ€์ˆ˜ ์™€ ์™ธ๋ถ€ ํ•จ์ˆ˜์˜ ๋ณ€์ˆ˜, ์ „์—ญ ๋ณ€์ˆ˜ ์— ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๋Š” ๊ถŒํ•œ์„ ๊ฐ€์ง€๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

  • ์ž๋ฐ” ์Šคํฌ๋ฆฝํŠธ์—์„œ closure๋Š” ํ•จ์ˆ˜ ๋‚ด๋ถ€์— ํ•จ์ˆ˜๋ฅผ ์ž‘์„ฑ๋  ๋•Œ๋งˆ๋‹ค ํ•จ๊ป˜ ์ƒ์„ฑ๋ฉ๋‹ˆ๋‹ค.

(ex)

  • ๋‚ด๋ถ€ ํ•จ์ˆ˜(innerFunc())์—์„œ ์™ธ๋ถ€ ํ•จ์ˆ˜(outerFunc())์˜ ์ง€์—ญ ๋ณ€์ˆ˜ outerVar์™€ ์ „์—ญ ๋ณ€์ˆ˜ globalVar์— ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ๊ฒฐ๊ณผ ๊ฐ’์€ "global/ outer/ inner"

    let globalVar = "global/"; //* ์ „์—ญ ๋ณ€์ˆ˜
    
    function outerFunc() {
      let outerVar = "outer/"; //* ์™ธ๋ถ€ ๋ณ€์ˆ˜
      function innerFunc() {
        let innerVar = "inner"; //* ๋‚ด๋ถ€ ๋ณ€์ˆ˜
        console.log(globalVar, outerVar, innerVar);
      }
      innerFunc();
    }
    outerFunc(); // global/ outer/ inner
    
    //* closure: innerFunc()
  • ๋ฐ˜๋ฉด์—, ์™ธ๋ถ€ ํ•จ์ˆ˜(outerFunc())์™€ ์ „์—ญ์—์„œ๋Š” ๋‚ด๋ถ€ ํ•จ์ˆ˜(innerFunc())์˜ ๋ณ€์ˆ˜ innerVar์— ์ ‘๊ทผํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.

    let globalVar = "global/"; //* ์ „์—ญ ๋ณ€์ˆ˜
    
    function outerFunc() {
      let outerVar = "outer/"; //* ์™ธ๋ถ€ ๋ณ€์ˆ˜
      function innerFunc() {
        let innerVar = "inner"; //* ๋‚ด๋ถ€ ๋ณ€์ˆ˜
      }
      console.log(innerVar); // Error: innerVar is not defined
    }
    console.log(innerVar); // Error: innerVar is not defined
    
    //* closure: innerFunc()

Closure Example

  • ํด๋กœ์ €๋ฅผ ํ†ตํ•ด ์›ํ•˜๋Š” ์‹œ์ ์— ๋‚ด๋ถ€ ํ•จ์ˆ˜๋ฅผ ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

    function studyClosure() {
      var name = "closure";
      return function () {
        console.log("Try to understand", name);
      };
    }
    
    // ์›ํ•˜๋Š” ์‹œ์ ์— ๋‚ด๋ถ€ํ•จ์ˆ˜๋ฅผ ์‹คํ–‰ํ•˜๊ธฐ ์œ„ํ•ด 'closure'๋ฅผ ํ™œ์šฉํ•ฉ๋‹ˆ๋‹ค.
    // studyClosure ํ•จ์ˆ˜๊ฐ€ ์‹คํ–‰๋˜๋ฉด, ๋ณ€์ˆ˜ myClosure๋Š” studyClosure์˜ ๋‚ด๋ถ€ํ•จ์ˆ˜๋ฅผ ๊ฐ€๋ฆฌํ‚ค๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.
    let myClosure = studyClosure();
    myClosure(); // Try to understand closure
  • ํด๋กœ์ €๋Š” ์ฃผ๋กœ private data๋ฅผ ์ €์žฅํ•˜๊ณ , ์ ‘๊ทผํ•˜๋Š”๋ฐ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค. (private ๋ณ€์ˆ˜)

    function secret() {
      let password = "***";
      return {
        getPassword() {
          alert(password);
        },
      };
    }
    // ๋‚ด๋ถ€ ํ•จ์ˆ˜์˜ ๋ณ€์ˆ˜๋Š” ์™ธ๋ถ€์—์„œ ์ ‘๊ทผํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.
    console.log(getPassword()); // Error: getPassword is not defined
    
    // ๋‚ด๋ถ€ ํ•จ์ˆ˜์˜ ๋ณ€์ˆ˜๋ฅผ ์™ธ๋ถ€์—์„œ ์ ‘๊ทผํ•˜๊ธฐ ์œ„ํ•ด์„œ 'closure'๋ฅผ ํ™œ์šฉํ•ฉ๋‹ˆ๋‹ค.
    // secret ํ•จ์ˆ˜๊ฐ€ ์‹คํ–‰๋˜๋ฉด, ๋ณ€์ˆ˜ privateVar๋Š” secret์˜ ๋‚ด๋ถ€ํ•จ์ˆ˜๋ฅผ ๊ฐ€๋ฆฌํ‚ค๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.
    const PrivateVar = secret(); // {getPassword: ฦ’}
    PrivateVar.getPassword();
    • getPassword ๋Š” secret ํ•จ์ˆ˜ ๋‚ด์—์„œ ์ •์˜๋œ password ์— ์ ‘๊ทผ ๊ฐ€๋Šฅํ•œ ๋‚ด๋ถ€ ํ•จ์ˆ˜(closure) ์ž…๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ์ด๋Ÿฐ ํ•จ์ˆ˜๋ฅผ ํŠน๊ถŒ ํ•จ์ˆ˜(privileged function) ๋ผ๊ณ  ๋ถ€๋ฅด๊ธฐ๋„ ํ•ฉ๋‹ˆ๋‹ค.

โ€ป Reference

[Javascript] Closure, Hoisting (ํด๋กœ์ €, ํ˜ธ์ด์ŠคํŒ…)

Master the JavaScript Interview: What is a Closure?

A simple guide to help you understand closures in JavaScript

[๋ฒˆ์—ญ] ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ์Šค์ฝ”ํ”„์™€ ํด๋กœ์ €(JavaScript Scope and Closures)

Javascript Closure? ํด๋กœ์ €? ๊ทธ๋ฆฌ๊ณ  ํด๋กœ์ € ์‚ฌ์šฉํ•ด module์„ ๋งŒ๋“ค๊ธฐ!

Last updated