μΉ΄ν…Œκ³ λ¦¬ 보관물: Javascript

Javascript

μžλ°” 슀크립트 ν΄λ‘œμ €μ™€ 읡λͺ… ν•¨μˆ˜ μ‹œλ„λŠ” λ‹€μŒκ³Ό κ°™μŠ΅λ‹ˆλ‹€. for(var

λ‚΄ μΉœκ΅¬μ™€ λ‚˜λŠ” ν˜„μž¬ JS의 폐쇄와 κ·Έλ ‡μ§€ μ•Šμ€ 것을 λ…Όμ˜ν•˜κ³  μžˆμŠ΅λ‹ˆλ‹€. μš°λ¦¬λŠ” 그것을 μ •ν™•ν•˜κ²Œ μ΄ν•΄ν•˜κ³  μ‹Άμ–΄ν•©λ‹ˆλ‹€.

이 예제λ₯Ό 보자. 카운트 루프가 있고 μ§€μ—°λœ μ½˜μ†”μ—μ„œ μΉ΄μš΄ν„° λ³€μˆ˜λ₯Ό μΈμ‡„ν•˜λ €κ³ ν•©λ‹ˆλ‹€. λ”°λΌμ„œ μΉ΄μš΄ν„° λ³€μˆ˜μ˜ 값을 μΊ‘μ²˜ν•˜μ—¬ ν΄λ‘œμ € λ₯Ό μ‚¬μš© setTimeoutν•˜μ—¬ N의 N λ°°λ₯Ό N으둜 μΈμ‡„ν•˜μ§€ μ•Šλ„λ‘ν•©λ‹ˆλ‹€.

μ—†λŠ” 잘λͺ»λœ μ†”λ£¨μ…˜ 폐쇄 λ˜λŠ” κ·Όμ²˜μ— 아무것도 폐쇄가 될 것이닀 :

for(var i = 0; i < 10; i++) {
    setTimeout(function() {
        console.log(i);
    }, 1000);
}

λ¬Όλ‘  i루프 ν›„ κ°’μ˜ 10 λ°° , 즉 10을 μΈμ‡„ν•©λ‹ˆλ‹€.

그의 μ‹œλ„λŠ” λ‹€μŒκ³Ό κ°™μŠ΅λ‹ˆλ‹€.

for(var i = 0; i < 10; i++) {
    (function(){
        var i2 = i;
        setTimeout(function(){
            console.log(i2);
        }, 1000)
    })();
}

μ˜ˆμƒλŒ€λ‘œ 0μ—μ„œ 9κΉŒμ§€ μΈμ‡„ν•©λ‹ˆλ‹€.

λ‚˜λŠ” κ·Έκ°€ 캑쳐 λ₯Ό μœ„ν•΄ ν΄λ‘œμ € λ₯Ό μ‚¬μš©ν•˜κ³  μžˆμ§€ μ•Šλ‹€κ³  말 iν–ˆμ§€λ§Œ κ·ΈλŠ” μžμ‹ μ„ μ£Όμž₯ν•œλ‹€. λ‚˜λŠ” for 루프 본문을 λ‹€λ₯Έ 루프 μ•ˆμ— λ„£κ³  (읡λͺ… ν•¨μˆ˜λ₯Όμ— 전달 ) 10 번 10을 λ‹€μ‹œ 인쇄 ν•˜μ—¬ ν΄λ‘œμ € λ₯Ό μ‚¬μš©ν•˜μ§€ μ•ŠλŠ”λ‹€λŠ” 것을 증λͺ… ν–ˆμŠ΅λ‹ˆλ‹€. λ‚˜λŠ” 그의 κΈ°λŠ₯을 μ €μž₯ν•˜λŠ” 경우 λ™μΌν•˜κ²Œ 적용 ν•˜κ³  μ‹€ν–‰ ν•œ ν›„ λ‚΄ μΈμˆ˜κ°€ μžˆλ‹€λŠ” κ²ƒμž…λ‹ˆλ‹€ κ·Έλž˜μ„œλ„ 10 λ°° (10)λ₯Ό 인쇄, 루프 κ·Έκ°€ μ •λ§ν•˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€ 캑처 의 값을 μžμ‹ μ˜ 버전 λ§Œλ“€κΈ°, ν•˜μ§€ ν΄λ‘œμ €λ₯Ό.setTimeoutsetTimeoutvari

λ‚˜μ˜ μ‹œλ„λŠ” :

for(var i = 0; i < 10; i++) {
    setTimeout((function(i2){
        return function() {
            console.log(i2);
        }
    })(i), 1000);
}

κ·Έλž˜μ„œ i( i2ν΄λ‘œμ € λ‚΄μ—μ„œ λͺ…λͺ… 된) 캑처 ν•˜μ§€λ§Œ 이제 λ‹€λ₯Έ ν•¨μˆ˜λ₯Ό λ°˜ν™˜ ν•˜κ³  이것을 μ „λ‹¬ν•©λ‹ˆλ‹€. ν•„μžμ˜ 경우 setTimeout에 전달 된 ν•¨μˆ˜κ°€ μ‹€μ œλ‘œ μΊ‘μ²˜ν•©λ‹ˆλ‹€ i.

이제 λˆ„κ°€ ν΄λ‘œμ €λ₯Ό μ‚¬μš©ν•˜κ³  있고 λˆ„κ°€ μ‚¬μš©ν•˜μ§€ μ•ŠμŠ΅λ‹ˆκΉŒ?

두 μ†”λ£¨μ…˜ λͺ¨λ‘ μ½˜μ†”μ—μ„œ 0μ—μ„œ 9κΉŒμ§€ μ§€μ—°λ˜μ–΄ μ›λž˜ 문제λ₯Ό ν•΄κ²°ν•˜μ§€λ§Œμ΄ 두 μ†”λ£¨μ…˜ 쀑 ν΄λ‘œμ € λ₯Ό μ‚¬μš© ν•˜μ—¬μ΄λ₯Ό μˆ˜ν–‰ν•˜λŠ” μ†”λ£¨μ…˜μ„ μ΄ν•΄ν•˜κ³  μ‹ΆμŠ΅λ‹ˆλ‹€ .



λ‹΅λ³€

νŽΈμ§‘μž μ£Ό : JavaScript의 λͺ¨λ“  κΈ°λŠ₯은이 κ²Œμ‹œλ¬Ό μ—μ„œ μ„€λͺ…ν•œ 폐쇄 μž…λ‹ˆλ‹€. κ·ΈλŸ¬λ‚˜ μš°λ¦¬λŠ” 이둠적 κ΄€μ μ—μ„œ ν₯미둜운 μ΄λŸ¬ν•œ κΈ°λŠ₯의 ν•˜μœ„ 집합을 μ‹λ³„ν•˜λŠ” λ°μ—λ§Œ 관심 이 μžˆμŠ΅λ‹ˆλ‹€. λ”°λΌμ„œ, 단어 ν΄λ‘œμ €μ— λŒ€ν•œ 언급은 달리 μ–ΈκΈ‰λ˜μ§€ μ•ŠλŠ” ν•œ μ΄λŸ¬ν•œ κΈ°λŠ₯의 μ„œλΈŒ μ„ΈνŠΈλ₯Ό μ§€μΉ­ ν•  것이닀.

ν΄λ‘œμ €μ— λŒ€ν•œ κ°„λ‹¨ν•œ μ„€λͺ… :

  1. κΈ°λŠ₯을 μˆ˜ν–‰ν•˜μ‹­μ‹œμ˜€. F라고 λΆ€λ₯΄κ² μŠ΅λ‹ˆλ‹€.
  2. F의 λͺ¨λ“  λ³€μˆ˜λ₯Ό λ‚˜μ—΄ν•˜μ‹­μ‹œμ˜€.
  3. λ³€μˆ˜λŠ” 두 κ°€μ§€ μœ ν˜•μΌ 수 μžˆμŠ΅λ‹ˆλ‹€.
    1. μ§€μ—­ λ³€μˆ˜ (λ°”μš΄λ“œ λ³€μˆ˜)
    2. λΉ„ κ΅­μ†Œ λ³€μˆ˜ (자유 λ³€μˆ˜)
  4. F에 자유 λ³€μˆ˜κ°€ μ—†μœΌλ©΄ ν΄λ‘œμ €κ°€ 될 수 μ—†μŠ΅λ‹ˆλ‹€.
  5. F에 자유 λ³€μˆ˜ ( F 의 μƒμœ„ λ²”μœ„μ— μ •μ˜ 된 )κ°€μžˆλŠ” 경우 :
    1. λ˜λŠ” F의 λΆ€λͺ¨ λ²”μœ„κ°€ μžˆμ–΄μ•Όν•©λ‹ˆλ‹€ 무료 λ³€μˆ˜κ°€ λ°”μΈλ”©λ©λ‹ˆλ‹€.
    2. Fκ°€ ν•΄λ‹Ή μƒμœ„ λ²”μœ„ μ™ΈλΆ€μ—μ„œ μ°Έμ‘° 되면 ν•΄λ‹Ή 자유 λ³€μˆ˜μ— λŒ€ν•œ ν΄λ‘œμ €κ°€λ©λ‹ˆλ‹€ .
    3. 이 자유 λ³€μˆ˜λ₯Ό ν΄λ‘œμ € F의 μƒμœ„ κ°’μ΄λΌκ³ ν•©λ‹ˆλ‹€.

이제 이것을 μ‚¬μš©ν•˜μ—¬ ν΄λ‘œμ €λ₯Ό μ‚¬μš©ν•˜λŠ” μ‚¬λžŒκ³Ό κ·Έλ ‡μ§€ μ•Šμ€ μ‚¬λžŒμ„ μ•Œμ•„ λ΄…μ‹œλ‹€ (μ„€λͺ…을 μœ„ν•΄ ν•¨μˆ˜ 이름을 μ§€μ •ν–ˆμŠ΅λ‹ˆλ‹€).

사둀 1 : 친ꡬ의 ν”„λ‘œκ·Έλž¨

for (var i = 0; i < 10; i++) {
    (function f() {
        var i2 = i;
        setTimeout(function g() {
            console.log(i2);
        }, 1000);
    })();
}

μœ„μ˜ ν”„λ‘œκ·Έλž¨μ—μ„œμ΄ 두 κ°€μ§€ κΈ°λŠ₯은 λ‹€μŒκ³Ό κ°™μŠ΅λ‹ˆλ‹€ f및 g. 그듀이 폐쇄인지 보자.

의 경우 f:

  1. λ³€μˆ˜λ₯Ό λ‚˜μ—΄ν•˜μ‹­μ‹œμ˜€.
    1. i2AλŠ” 둜컬 λ³€μˆ˜.
    2. iAλŠ” 무료 λ³€μˆ˜.
    3. setTimeoutAλŠ” 무료 λ³€μˆ˜.
    4. gAλŠ” 둜컬 λ³€μˆ˜.
    5. consoleAλŠ” 무료 λ³€μˆ˜.
  2. 각 자유 λ³€μˆ˜κ°€ 바인딩 된 μƒμœ„ λ²”μœ„λ₯Ό μ°ΎμœΌμ‹­μ‹œμ˜€.
    1. iλ˜λŠ” 바인딩 전역에.
    2. setTimeoutλ˜λŠ” 바인딩 전역에.
    3. consoleλ˜λŠ” 바인딩 전역에.
  3. μ–΄λ–€ λ²”μœ„μ—μ„œ ν•¨μˆ˜κ°€ μ°Έμ‘° λ©λ‹ˆκΉŒ? μ „μ—­ λ²”μœ„ .
    1. λ”°λΌμ„œ 에 μ˜ν•΄ 폐쇄i λ˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€ .f
    2. λ”°λΌμ„œ 에 μ˜ν•΄ 폐쇄setTimeout λ˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€ .f
    3. λ”°λΌμ„œ 에 μ˜ν•΄ 폐쇄console λ˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€ .f

λ”°λΌμ„œ κΈ°λŠ₯ f은 폐쇄가 μ•„λ‹™λ‹ˆλ‹€.

의 경우 g:

  1. λ³€μˆ˜λ₯Ό λ‚˜μ—΄ν•˜μ‹­μ‹œμ˜€.
    1. consoleAλŠ” 무료 λ³€μˆ˜.
    2. i2AλŠ” 무료 λ³€μˆ˜.
  2. 각 자유 λ³€μˆ˜κ°€ 바인딩 된 μƒμœ„ λ²”μœ„λ₯Ό μ°ΎμœΌμ‹­μ‹œμ˜€.
    1. consoleλ˜λŠ” 바인딩 전역에.
    2. i2λ˜λŠ” 바인딩 의 λ²”μœ„μ— f.
  3. μ–΄λ–€ λ²”μœ„μ—μ„œ ν•¨μˆ˜κ°€ μ°Έμ‘° λ©λ‹ˆκΉŒ? 의 λ²”μœ„setTimeout .
    1. λ”°λΌμ„œ 에 μ˜ν•΄ 폐쇄console λ˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€ .g
    2. κ·ΈλŸ¬λ―€λ‘œ i2λ˜μ–΄ λ‹«ν˜€ μ˜ν•΄ g.

λ”°λΌμ„œ ν•¨μˆ˜λŠ” g자유 λ³€μˆ˜μ— λŒ€ν•œ νμ‡„μž…λ‹ˆλ‹€ i2(λŒ€ν•œ upvalue이닀 g) 경우 κ°€μžˆμ–΄ μ°Έμ‘° λ‚΄μ—μ„œκ°€ setTimeout.

λ‹Ήμ‹ μ—κ²Œ λ‚˜μœ 점 : μΉœκ΅¬κ°€ 폐쇄λ₯Ό μ‚¬μš©ν•˜κ³  μžˆμŠ΅λ‹ˆλ‹€. λ‚΄λΆ€ κΈ°λŠ₯은 νμ‡„μž…λ‹ˆλ‹€.

사둀 2 : ν”„λ‘œκ·Έλž¨

for (var i = 0; i < 10; i++) {
    setTimeout((function f(i2) {
        return function g() {
            console.log(i2);
        };
    })(i), 1000);
}

μœ„μ˜ ν”„λ‘œκ·Έλž¨μ—μ„œμ΄ 두 κ°€μ§€ κΈ°λŠ₯은 λ‹€μŒκ³Ό κ°™μŠ΅λ‹ˆλ‹€ f및 g. 그듀이 폐쇄인지 보자.

의 경우 f:

  1. λ³€μˆ˜λ₯Ό λ‚˜μ—΄ν•˜μ‹­μ‹œμ˜€.
    1. i2AλŠ” 둜컬 λ³€μˆ˜.
    2. gAλŠ” 둜컬 λ³€μˆ˜.
    3. consoleAλŠ” 무료 λ³€μˆ˜.
  2. 각 자유 λ³€μˆ˜κ°€ 바인딩 된 μƒμœ„ λ²”μœ„λ₯Ό μ°ΎμœΌμ‹­μ‹œμ˜€.
    1. consoleλ˜λŠ” 바인딩 전역에.
  3. μ–΄λ–€ λ²”μœ„μ—μ„œ ν•¨μˆ˜κ°€ μ°Έμ‘° λ©λ‹ˆκΉŒ? μ „μ—­ λ²”μœ„ .
    1. λ”°λΌμ„œ 에 μ˜ν•΄ 폐쇄console λ˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€ .f

λ”°λΌμ„œ κΈ°λŠ₯ f은 폐쇄가 μ•„λ‹™λ‹ˆλ‹€.

의 경우 g:

  1. λ³€μˆ˜λ₯Ό λ‚˜μ—΄ν•˜μ‹­μ‹œμ˜€.
    1. consoleAλŠ” 무료 λ³€μˆ˜.
    2. i2AλŠ” 무료 λ³€μˆ˜.
  2. 각 자유 λ³€μˆ˜κ°€ 바인딩 된 μƒμœ„ λ²”μœ„λ₯Ό μ°ΎμœΌμ‹­μ‹œμ˜€.
    1. consoleλ˜λŠ” 바인딩 전역에.
    2. i2λ˜λŠ” 바인딩 의 λ²”μœ„μ— f.
  3. μ–΄λ–€ λ²”μœ„μ—μ„œ ν•¨μˆ˜κ°€ μ°Έμ‘° λ©λ‹ˆκΉŒ? 의 λ²”μœ„setTimeout .
    1. λ”°λΌμ„œ 에 μ˜ν•΄ 폐쇄console λ˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€ .g
    2. κ·ΈλŸ¬λ―€λ‘œ i2λ˜μ–΄ λ‹«ν˜€ μ˜ν•΄ g.

λ”°λΌμ„œ ν•¨μˆ˜λŠ” g자유 λ³€μˆ˜μ— λŒ€ν•œ νμ‡„μž…λ‹ˆλ‹€ i2(λŒ€ν•œ upvalue이닀 g) 경우 κ°€μžˆμ–΄ μ°Έμ‘° λ‚΄μ—μ„œκ°€ setTimeout.

당신을 μœ„ν•΄ 쒋은 : 당신은 폐쇄λ₯Ό μ‚¬μš©ν•˜κ³  μžˆμŠ΅λ‹ˆλ‹€. λ‚΄λΆ€ κΈ°λŠ₯은 νμ‡„μž…λ‹ˆλ‹€.

κ·Έλž˜μ„œ λ‹Ήμ‹ κ³Ό λ‹Ήμ‹ μ˜ 친ꡬ λͺ¨λ‘ 폐쇄λ₯Ό μ‚¬μš©ν•˜κ³  μžˆμŠ΅λ‹ˆλ‹€. λ§λ‹€νˆΌμ„ λ©ˆμΆ”μ‹­μ‹œμ˜€. ν΄λ‘œμ €μ˜ κ°œλ…κ³Ό 두 μ‚¬λžŒ λͺ¨λ‘λ₯Ό μ‹λ³„ν•˜λŠ” 방법을 λͺ…ν™•ν•˜κ²Œ μ •λ¦¬ν–ˆμœΌλ©΄ν•©λ‹ˆλ‹€.

νŽΈμ§‘ : λͺ¨λ“  ν•¨μˆ˜κ°€ μ™œ νμ‡„λ˜λŠ”μ§€μ— λŒ€ν•œ κ°„λ‹¨ν•œ μ„€λͺ… (ν¬λ ˆλ”§ @ ν”Όν„°) :

λ¨Όμ € λ‹€μŒ ν”„λ‘œκ·Έλž¨μ„ κ³ λ €ν•΄ λ΄…μ‹œλ‹€ ( μ œμ–΄μž…λ‹ˆλ‹€ ).

lexicalScope();

function lexicalScope() {
    var message = "This is the control. You should be able to see this message being alerted.";

    regularFunction();

    function regularFunction() {
        alert(eval("message"));
    }
}
  1. μš°λ¦¬λŠ” λͺ¨λ‘ μ•Œκ³  lexicalScope및 regularFunctionνμ‡„ν•˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€ μœ„μ˜ μ •μ˜μ—μ„œ .
  2. ν”„λ‘œκ·Έλž¨μ„ μ‹€ν–‰ν•  λ•Œ ν΄λ‘œμ €κ°€ μ•„λ‹ˆκΈ° λ•Œλ¬Έμ— κ²½κ³ λ₯Όλ°›μ„ κ²ƒμœΌλ‘œ μ˜ˆμƒ message λ©λ‹ˆλ‹€ (예 : λΆ€λͺ¨ λ²”μœ„μ˜ λͺ¨λ“  λ³€μˆ˜μ— μ•‘μ„ΈμŠ€ ν•  수 있음 ). regularFunctionmessage
  3. μš°λ¦¬κ°€ ν”„λ‘œκ·Έλž¨μ„ μ‹€ν–‰ν•  λ•Œ μ‹€μ œλ‘œ κ²½κ³  λ˜λŠ” 것을 κ΄€μ°° ν•©λ‹ˆλ‹€ message.

λ‹€μŒ ν”„λ‘œκ·Έλž¨μ„ κ³ λ €ν•΄ λ΄…μ‹œλ‹€ ( λŒ€μ•ˆμž…λ‹ˆλ‹€ ).

var closureFunction = lexicalScope();

closureFunction();

function lexicalScope() {
    var message = "This is the alternative. If you see this message being alerted then in means that every function in JavaScript is a closure.";

    return function closureFunction() {
        alert(eval("message"));
    };
}
  1. μš°λ¦¬λŠ” 단지 μœ„μ˜ μ •μ˜μ—μ„œclosureFunction 폐쇄 된 κ²ƒμž„μ„ μ•Œκ³  μžˆμŠ΅λ‹ˆλ‹€.
  2. μš°λ¦¬κ°€ ν”„λ‘œκ·Έλž¨μ„ μ‹€ν–‰ν•˜λ©΄ μš°λ¦¬λŠ” κΈ°λŒ€ message κ²½κ³ λ₯Ό ν•  수 μ—†μŠ΅λ‹ˆλ‹€ λ•Œλ¬Έμ— closureFunction (즉, 그것은 단지 λͺ¨λ“ μ— μ•‘μ„ΈμŠ€ ν•  μˆ˜μžˆλŠ” νμ‡„μž…λ‹ˆλ‹€ λΉ„ μ§€μ—­ λ³€μˆ˜ 에 ν•¨μˆ˜κ°€ μž‘μ„± 될 λ•Œ ( 이 닡변을 μ°Έμ‘° -이 ν¬ν•¨λ˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€μ΄) message).
  3. ν”„λ‘œκ·Έλž¨μ„ μ‹€ν–‰ν•  λ•Œ μ‹€μ œλ‘œ κ²½κ³  ν•˜κ³  있음 을 κ΄€μ°° ν•©λ‹ˆλ‹€ message.

μš°λ¦¬λŠ” μ΄κ²ƒμœΌλ‘œλΆ€ν„° 무엇을 μΆ”λ‘ ν•©λ‹ˆκΉŒ?

  1. JavaScript μΈν„°ν”„λ¦¬ν„°λŠ” ν΄λ‘œμ €λ₯Ό λ‹€λ₯Έ ν•¨μˆ˜λ₯Ό μ²˜λ¦¬ν•˜λŠ” 방식과 λ‹€λ₯΄κ²Œ μ·¨κΈ‰ν•˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€.
  2. λͺ¨λ“  κΈ°λŠ₯μ—λŠ” μŠ€μ½”ν”„ 체인 이 ν¬ν•¨λ©λ‹ˆλ‹€. ν΄λ‘œμ €μ—λŠ” λ³„λ„μ˜ μ°Έμ‘° ν™˜κ²½ 이 μ—†μŠ΅λ‹ˆλ‹€ .
  3. ν΄λ‘œμ €λŠ” λ‹€λ₯Έ λͺ¨λ“  κΈ°λŠ₯κ³Ό κ°™μŠ΅λ‹ˆλ‹€. μš°λ¦¬λŠ” 그것듀이 그듀이 μ†ν•œ λ²”μœ„ λ°–μ˜ λ²”μœ„μ—μ„œ μ°Έμ‘° 될 λ•Œ 그것듀을 ν΄λ‘œμ €λΌκ³  λΆ€λ¦…λ‹ˆλ‹€ . 이것은 ν₯미둜운 경우 이기 λ•Œλ¬Έ μž…λ‹ˆλ‹€.

λ‹΅λ³€

closureμ •μ˜ 에 λ”°λ₯΄λ©΄ :

β€œν΄λ‘œμ €β€λŠ” λ³€μˆ˜ λ₯Ό λ¬ΆλŠ” ν™˜κ²½ (ν‘œν˜„μ„ β€œλ‹«λŠ”β€) κ³Ό ν•¨κ»˜ 자유 λ³€μˆ˜λ₯Ό κ°€μ§ˆ 수 μžˆλŠ” ν‘œν˜„μ‹ (일반적으둜 ν•¨μˆ˜)μž…λ‹ˆλ‹€ .

당신이 μ‚¬μš©ν•˜λŠ” closure당신은 ν•¨μˆ˜μ˜ μ™ΈλΆ€μ—μ„œ μ •μ˜ 된 λ³€μˆ˜λ₯Ό μ‚¬μš©ν•˜λŠ” ν•¨μˆ˜λ₯Ό μ •μ˜ν•©λ‹ˆλ‹€. (μš°λ¦¬λŠ” λ³€μˆ˜λ₯Ό 자유 λ³€μˆ˜ 라고 λΆ€λ¦…λ‹ˆλ‹€ ).
그듀은 λͺ¨λ‘ μ‚¬μš©ν•©λ‹ˆλ‹€ closure(첫 번째 μ˜ˆμ—μ„œλ„).


λ‹΅λ³€

κ°„λ‹¨νžˆ λ§ν•΄μ„œ μžλ°” 슀크립트 ν΄λ‘œμ € 둜 κΈ°λŠ₯ ν•  수 μ•‘μ„ΈμŠ€λ₯Ό κ°€λ³€ λ˜λŠ” μ–΄νœ˜ – λΆ€λͺ¨ ν•¨μˆ˜μ—μ„œ 선언을 .

더 μžμ„Έν•œ μ„€λͺ…을 보자. ν΄λ‘œμ €λ₯Ό μ΄ν•΄ν•˜λ €λ©΄ JavaScript의 λ³€μˆ˜ λ²”μœ„λ₯Ό μ΄ν•΄ν•˜λŠ” 것이 μ€‘μš”ν•©λ‹ˆλ‹€.

λ²”μœ„

JavaScript λ²”μœ„λŠ” ν•¨μˆ˜λ‘œ μ •μ˜λ©λ‹ˆλ‹€. λͺ¨λ“  ν•¨μˆ˜λŠ” μƒˆλ‘œμš΄ λ²”μœ„λ₯Ό μ •μ˜ν•©λ‹ˆλ‹€.

λ‹€μŒ 예제λ₯Ό κ³ λ €ν•˜μ‹­μ‹œμ˜€.

function f()
{//begin of scope f
  var foo='hello'; //foo is declared in scope f
  for(var i=0;i<2;i++){//i is declared in scope f
     //the for loop is not a function, therefore we are still in scope f
     var bar = 'Am I accessible?';//bar is declared in scope f
     console.log(foo);
  }
  console.log(i);
  console.log(bar);
}//end of scope f

f 인쇄λ₯Ό 호좜

hello
hello
2
Am I Accessible?

이제 gλ‹€λ₯Έ ν•¨μˆ˜ 내에 μ •μ˜ 된 ν•¨μˆ˜κ°€μžˆλŠ” 경우λ₯Ό κ³ λ €ν•΄ λ΄…μ‹œλ‹€ f.

function f()
{//begin of scope f
  function g()
  {//being of scope g
    /*...*/
  }//end of scope g
  /*...*/
}//end of scope f

f의 μ–΄νœ˜ λΆ€λͺ¨ λ₯Ό 호좜 ν•©λ‹ˆλ‹€ g. μ•žμ—μ„œ μ„€λͺ…ν–ˆλ“―이 이제 μš°λ¦¬λŠ” 두 κ°€μ§€ λ²”μœ„λ₯Ό κ°–μŠ΅λ‹ˆλ‹€. λ²”μœ„ f와 λ²”μœ„g .

κ·ΈλŸ¬λ‚˜ ν•œ λ²”μœ„λŠ” λ‹€λ₯Έ λ²”μœ„ 내에 β€œλ‚΄β€μžˆμœΌλ©°, ν•˜μœ„ ν•¨μˆ˜μ˜ λ²”μœ„λŠ” λΆ€λͺ¨ ν•¨μˆ˜ λ²”μœ„μ˜ μΌλΆ€μž…λ‹ˆκΉŒ? λΆ€λͺ¨ ν•¨μˆ˜μ˜ λ²”μœ„μ—μ„œ μ„ μ–Έ 된 λ³€μˆ˜λŠ” μ–΄λ–»κ²Œλ©λ‹ˆκΉŒ? ν•˜μœ„ κΈ°λŠ₯의 λ²”μœ„μ—μ„œ μ•‘μ„ΈμŠ€ ν•  수 μžˆμŠ΅λ‹ˆκΉŒ? λ°”λ‘œ 폐쇄가 μ‹œμž‘λ˜λŠ” κ³³μž…λ‹ˆλ‹€.

폐쇄

JavaScriptμ—μ„œ ν•¨μˆ˜ gλŠ” λ²”μœ„μ— μ„ μ–Έ 된 λ³€μˆ˜ g뿐만 μ•„λ‹ˆλΌ μƒμœ„ ν•¨μˆ˜ λ²”μœ„μ— μ„ μ–Έ 된 λ³€μˆ˜μ—λ„ μ•‘μ„ΈμŠ€ ν•  수 μžˆμŠ΅λ‹ˆλ‹€.f .

λ‹€μŒμ„ κ³ λ €ν•˜μ‹­μ‹œμ˜€.

function f()//lexical parent function
{//begin of scope f
  var foo='hello'; //foo declared in scope f
  function g()
  {//being of scope g
    var bar='bla'; //bar declared in scope g
    console.log(foo);
  }//end of scope g
  g();
  console.log(bar);
}//end of scope f

f 인쇄λ₯Ό 호좜

hello
undefined

라인을 보자 console.log(foo);. 이 μ‹œμ μ—μ„œ μš°λ¦¬λŠ” λ²”μœ„ 내에 있으며 scope 에 μ„ μ–Έ 된 gλ³€μˆ˜μ— μ•‘μ„ΈμŠ€ν•˜λ €κ³ ν•©λ‹ˆλ‹€ . κ·ΈλŸ¬λ‚˜ μ•žμ—μ„œ μ–ΈκΈ‰ν–ˆλ“―μ΄ μ—¬κΈ°μ„œλŠ” μ–΄νœ˜ λΆ€λͺ¨ ν•¨μˆ˜μ— μ„ μ–Έ 된 λ³€μˆ˜μ— μ•‘μ„ΈμŠ€ ν•  수 μžˆμŠ΅λ‹ˆλ‹€. 의 μ–΄νœ˜ λΆ€λͺ¨μž…λ‹ˆλ‹€ . λ”°λΌμ„œ μΈμ‡„λ©λ‹ˆλ‹€.
이제 라인을 보자 . 이 μ‹œμ μ—μ„œ μš°λ¦¬λŠ” λ²”μœ„ 내에 있으며 scope 에 μ„ μ–Έ 된 λ³€μˆ˜μ— μ•‘μ„ΈμŠ€ν•˜λ €κ³ ν•©λ‹ˆλ‹€ . ν˜„μž¬ λ²”μœ„μ—μ„œ μ„ μ–Έλ˜μ§€ μ•Šμ•˜μœΌλ©° ν•¨μˆ˜ κ°€μ˜ λΆ€λͺ¨κ°€ μ•„λ‹ˆλ―€ 둜 μ •μ˜λ˜μ§€ μ•Šμ•˜μŠ΅λ‹ˆλ‹€.foofgfhello
console.log(bar);fbargbargfbar

μ‹€μ œλ‘œ μš°λ¦¬λŠ” μ–΄νœ˜ β€œgrand parentβ€ν•¨μˆ˜μ˜ λ²”μœ„μ—μ„œ μ„ μ–Έ 된 λ³€μˆ˜μ— μ•‘μ„ΈμŠ€ ν•  μˆ˜λ„ μžˆμŠ΅λ‹ˆλ‹€. λ”°λΌμ„œ ν•¨μˆ˜ h내에 μ •μ˜ 된 ν•¨μˆ˜κ°€ μžˆλ‹€λ©΄g

function f()
{//begin of scope f
  function g()
  {//being of scope g
    function h()
    {//being of scope h
      /*...*/
    }//end of scope h
    /*...*/
  }//end of scope g
  /*...*/
}//end of scope f

λ‹€μŒ hν•¨μˆ˜μ˜ λ²”μœ„μ— μ„ μ–Έ 된 λͺ¨λ“  λ³€μˆ˜μ— μ•‘μ„ΈμŠ€ ν•  μˆ˜μžˆμ„ 것 h, g등을 f. 이것은 ν΄λ‘œμ € 둜 μ΄λ£¨μ–΄μ§‘λ‹ˆλ‹€ . JavaScript ν΄λ‘œμ € μ—μ„œλŠ” μ–΄νœ˜ λΆ€λͺ¨ ν•¨μˆ˜, μ–΄νœ˜ κ·Έλžœλ“œ λΆ€λͺ¨ ν•¨μˆ˜, μ–΄νœ˜ κ·Έλžœλ“œ λΆ€λͺ¨ ν•¨μˆ˜ λ“±μ—μ„œ μ„ μ–Έ 된 λͺ¨λ“  λ³€μˆ˜μ— μ•‘μ„ΈμŠ€ ν•  수 μžˆμŠ΅λ‹ˆλ‹€. μ΄λŠ” λ²”μœ„ 체인 으둜 λ³Ό 수 μžˆμŠ΅λ‹ˆλ‹€ . scope of current function -> scope of lexical parent function -> scope of lexical grand parent function -> ... μ–΄νœ˜ λΆ€λͺ¨κ°€μ—†λŠ” λ§ˆμ§€λ§‰ λΆ€λͺ¨ ν•¨μˆ˜κΉŒμ§€

μœˆλ„μš° 객체

μ‹€μ œλ‘œ 체인은 λ§ˆμ§€λ§‰ λΆ€λͺ¨ ν•¨μˆ˜μ—μ„œ λ©ˆμΆ”μ§€ μ•ŠμŠ΅λ‹ˆλ‹€. νŠΉλ³„ν•œ λ²”μœ„κ°€ ν•˜λ‚˜ 더 μžˆμŠ΅λ‹ˆλ‹€. μ „μ—­ λ²”μœ„ . ν•¨μˆ˜μ—μ„œ μ„ μ–Έλ˜μ§€ μ•Šμ€ λͺ¨λ“  λ³€μˆ˜λŠ” μ „μ—­ λ²”μœ„μ—μ„œ μ„ μ–Έ 된 κ²ƒμœΌλ‘œ κ°„μ£Όλ©λ‹ˆλ‹€. κΈ€λ‘œλ²Œ μŠ€μ½”ν”„μ—λŠ” 두 κ°€μ§€ νŠΉμ„±μ΄ μžˆμŠ΅λ‹ˆλ‹€.

  • μ „μ—­ λ²”μœ„μ—μ„œ μ„ μ–Έ 된 λͺ¨λ“  λ³€μˆ˜λŠ” λͺ¨λ“  κ³³μ—μ„œ μ•‘μ„ΈμŠ€ κ°€λŠ₯
  • μ „μ—­ λ²”μœ„μ—μ„œ μ„ μ–Έ 된 λ³€μˆ˜λŠ” window객체 의 속성에 ν•΄λ‹Ή ν•©λ‹ˆλ‹€.

λ”°λΌμ„œ fooμ „μ—­ λ²”μœ„μ—μ„œ λ³€μˆ˜λ₯Ό μ„ μ–Έν•˜λŠ” 두 κ°€μ§€ 방법이 μžˆμŠ΅λ‹ˆλ‹€ . ν•¨μˆ˜μ—μ„œ μ„ μ–Έν•˜μ§€ μ•Šκ±°λ‚˜ fooμœˆλ„μš° 객체 의 속성 을 μ„€μ •ν•˜μ—¬ .

두 μ‹œλ„ λͺ¨λ‘ ν΄λ‘œμ €λ₯Ό μ‚¬μš©ν•©λ‹ˆλ‹€.

더 μžμ„Έν•œ μ„€λͺ…을 μ½μ—ˆμœΌλ―€λ‘œ 이제 두 μ†”λ£¨μ…˜ λͺ¨λ‘ ν΄λ‘œμ €λ₯Ό μ‚¬μš©ν•˜λŠ” 것이 λΆ„λͺ… ν•  수 μžˆμŠ΅λ‹ˆλ‹€. κ·ΈλŸ¬λ‚˜ ν™•μ‹€ν•˜κ²Œ 증거λ₯Ό λ§Œλ“€μ–΄ λ΄…μ‹œλ‹€.

μƒˆλ‘œμš΄ ν”„λ‘œκ·Έλž˜λ° μ–Έμ–΄λ₯Ό λ§Œλ“€μ–΄ 보자. JavaScript-No-Closure. μ΄λ¦„μ—μ„œ μ•Œ 수 μžˆλ“―μ΄ JavaScript-No-ClosureλŠ” ν΄λ‘œμ €λ₯Ό μ§€μ›ν•˜μ§€ μ•ŠλŠ”λ‹€λŠ” 점을 μ œμ™Έν•˜λ©΄ JavaScript와 λ™μΌν•©λ‹ˆλ‹€.

λ‹€μ‹œ 말해;

var foo = 'hello';
function f(){console.log(foo)};
f();
//JavaScript-No-Closure prints undefined
//JavaSript prints hello

자, JavaScript-No-Closureλ₯Ό μ‚¬μš©ν•˜λŠ” 첫 번째 μ†”λ£¨μ…˜μ—μ„œ μ–΄λ–€ 일이 λ°œμƒν•˜λŠ”μ§€ λ΄…μ‹œλ‹€.

for(var i = 0; i < 10; i++) {
  (function(){
    var i2 = i;
    setTimeout(function(){
        console.log(i2); //i2 is undefined in JavaScript-No-Closure 
    }, 1000)
  })();
}

λ”°λΌμ„œ 이것은 μΈμ‡„λ©λ‹ˆλ‹€ undefined JavaScript-No-Closureμ—μ„œ 10 번 .

λ”°λΌμ„œ 첫 번째 μ†”λ£¨μ…˜μ€ ν΄λ‘œμ €λ₯Ό μ‚¬μš©ν•©λ‹ˆλ‹€.

두 번째 해결책을 보자.

for(var i = 0; i < 10; i++) {
  setTimeout((function(i2){
    return function() {
        console.log(i2); //i2 is undefined in JavaScript-No-Closure
    }
  })(i), 1000);
}

λ”°λΌμ„œ 이것은 μΈμ‡„λ©λ‹ˆλ‹€ undefined JavaScript-No-Closureμ—μ„œ 10 번 .

두 μ†”λ£¨μ…˜ λͺ¨λ‘ ν΄λ‘œμ €λ₯Ό μ‚¬μš©ν•©λ‹ˆλ‹€.

νŽΈμ§‘ :이 3 개의 μ½”λ“œ 슀 λ‹ˆνŽ«μ΄ μ „μ—­ λ²”μœ„μ— μ •μ˜λ˜μ–΄ μžˆμ§€ μ•Šμ€ κ²ƒμœΌλ‘œ κ°€μ •ν•©λ‹ˆλ‹€. κ·Έλ ‡μ§€ μ•ŠμœΌλ©΄ λ³€μˆ˜ foo와 객체가 객체에 i바인딩 windowλ˜λ―€λ‘œ windowJavaScript와 JavaScript-No-Closure 의 객체λ₯Ό 톡해 μ•‘μ„ΈμŠ€ ν•  수 μžˆμŠ΅λ‹ˆλ‹€ .


λ‹΅λ³€

λ‚˜λŠ” λˆ„κ΅°κ°€κ°€ 이것을 μ„€λͺ…ν•˜λŠ” 방식에 κ²°μ½” ν–‰λ³΅ν•˜μ§€ μ•Šμ•˜μŠ΅λ‹ˆλ‹€.

ν΄λ‘œμ €λ₯Ό μ΄ν•΄ν•˜λŠ” μ—΄μ‡ λŠ” ν΄λ‘œμ €κ°€μ—†λŠ” JS의 λͺ¨μŠ΅μ„ μ΄ν•΄ν•˜λŠ” κ²ƒμž…λ‹ˆλ‹€.

ν΄λ‘œμ €κ°€ μ—†μœΌλ©΄ 였λ₯˜κ°€ λ°œμƒν•©λ‹ˆλ‹€.

function outerFunc(){
    var outerVar = 'an outerFunc var';
    return function(){
        alert(outerVar);
    }
}

outerFunc()(); //returns inner function and fires it

outerFuncκ°€ κ°€μƒμ˜ ν΄λ‘œμ € λΉ„ν™œμ„±ν™” λ²„μ „μ˜ JavaScript둜 λ°˜ν™˜λ˜λ©΄ outerVar에 λŒ€ν•œ μ°Έμ‘°λŠ” κ°€λΉ„μ§€ μˆ˜μ§‘λ˜μ–΄ λ‚΄λΆ€ ν•¨μˆ˜κ°€ μ°Έμ‘° ν•  μˆ˜μžˆλŠ” 뢀뢄이 μ—†μ–΄μ§‘λ‹ˆλ‹€.

ν΄λ‘œμ €λŠ” 본질적으둜 λ‚΄λΆ€ ν•¨μˆ˜κ°€ μ™ΈλΆ€ ν•¨μˆ˜μ˜ λ³€μˆ˜λ₯Ό μ°Έμ‘° ν•  λ•Œ ν•΄λ‹Ή λ³€μˆ˜κ°€ μ‘΄μž¬ν•  수 μžˆλ„λ‘ν•˜λŠ” 특수 κ·œμΉ™μž…λ‹ˆλ‹€. ν΄λ‘œμ €λ₯Ό μ‚¬μš©ν•˜λ©΄ μ™ΈλΆ€ ν•¨μˆ˜κ°€ μˆ˜ν–‰λ˜κ±°λ‚˜ 포인트λ₯Ό κΈ°μ–΅ν•˜λŠ” 데 λ„μ›€μ΄λ˜λŠ” 경우 β€˜λ‹«νžŒβ€™ν›„μ—λ„ μ°Έμ‘° 된 varκ°€ μœ μ§€λ©λ‹ˆλ‹€.

ν΄λ‘œμ €λ₯Ό μ‚¬μš©ν•˜λ”λΌλ„ λ‘œμ»¬μ„ μ°Έμ‘°ν•˜λŠ” λ‚΄λΆ€ νŽ‘ν¬κ°€μ—†λŠ” ν•¨μˆ˜μ—μ„œ 둜컬 var의 수λͺ…μ£ΌκΈ°λŠ” ν΄λ‘œμ €λ¦¬μŠ€ λ²„μ „μ—μ„œμ™€ λ™μΌν•˜κ²Œ μž‘λ™ν•©λ‹ˆλ‹€. ν•¨μˆ˜κ°€ μ™„λ£Œλ˜λ©΄ μ§€μ—­ 주민은 κ°€λΉ„μ§€ μˆ˜μ§‘μ„λ°›μŠ΅λ‹ˆλ‹€.

λ‚΄λΆ€ νŽ‘ν¬μ—μ„œ μ™ΈλΆ€ var에 λŒ€ν•œ μ°Έμ‘°κ°€ 있으면 도어 잼이 μ°Έμ‘° var에 λŒ€ν•œ κ°€λΉ„μ§€ μˆ˜μ§‘ 방식과 μœ μ‚¬ν•©λ‹ˆλ‹€.

ν΄λ‘œμ €λ₯Ό λ³΄λŠ” 더 μ •ν™•ν•œ 방법은 λ‚΄λΆ€ ν•¨μˆ˜κ°€ 기본적으둜 λ‚΄λΆ€ λ²”μœ„λ₯Ό 자체 λ²”μœ„ μ†Œλ¦¬λ‘œ μ‚¬μš©ν•œλ‹€λŠ” κ²ƒμž…λ‹ˆλ‹€.

κ·ΈλŸ¬λ‚˜ μ°Έμ‘° 된 μ»¨ν…μŠ€νŠΈλŠ” 사싀 μŠ€λƒ… μƒ·κ³ΌλŠ” 달리 μ˜κ΅¬μ μž…λ‹ˆλ‹€. μ™ΈλΆ€ ν•¨μˆ˜μ˜ 둜컬 λ³€μˆ˜λ₯Ό 계속 μ¦κ°€μ‹œν‚€κ³  λ‘œκΉ…ν•˜λŠ” λ°˜ν™˜ 된 λ‚΄λΆ€ ν•¨μˆ˜λ₯Ό 반볡적으둜 μ‹€ν–‰ν•˜λ©΄ 더 높은 값을 κ²½κ³ ν•©λ‹ˆλ‹€.

function outerFunc(){
    var incrementMe = 0;
    return function(){ incrementMe++; console.log(incrementMe); }
}
var inc = outerFunc();
inc(); //logs 1
inc(); //logs 2

λ‹΅λ³€

λ‘˜ λ‹€ ν΄λ‘œμ €λ₯Ό μ‚¬μš©ν•˜κ³  μžˆμŠ΅λ‹ˆλ‹€.

λ‚˜λŠ” μ—¬κΈ° Wikipedia μ •μ˜ 와 ν•¨κ»˜ 갈 것이닀.

컴퓨터 κ³Όν•™μ—μ„œ ν΄λ‘œμ € (μ–΄νœ˜ 폐쇄 λ˜λŠ” ν•¨μˆ˜ ν΄λ‘œμ €)λŠ” μ°Έμ‘° ν™˜κ²½κ³Ό ν•¨κ»˜ ν•¨μˆ˜μ— λŒ€ν•œ ν•¨μˆ˜ λ˜λŠ” μ°Έμ‘°μž…λ‹ˆλ‹€. ν•΄λ‹Ή ν•¨μˆ˜μ˜ 둜컬 λ³€μˆ˜κ°€ μ•„λ‹Œ 각 λ³€μˆ˜ (자유 λ³€μˆ˜λΌκ³ λ„ 함)에 λŒ€ν•œ μ°Έμ‘°λ₯Ό μ €μž₯ν•˜λŠ” ν…Œμ΄λΈ” . 일반 ν•¨μˆ˜ 포인터와 달리 ν΄λ‘œμ €λŠ” ν•¨μˆ˜κ°€ 즉각적인 μ–΄νœ˜ λ²”μœ„λ₯Ό λ²—μ–΄λ‚œ κ²½μš°μ—λ„ 둜컬이 μ•„λ‹Œ λ³€μˆ˜μ— μ•‘μ„ΈμŠ€ ν•  수 μžˆλ„λ‘ν•©λ‹ˆλ‹€.

친ꡬ의 μ‹œλ„ iλŠ” 값을 κ°€μ Έ μ™€μ„œ λ‘œμ»¬μ— μ €μž₯ν•  사본을 λ§Œλ“€μ–΄ 둜컬이 μ•„λ‹Œ λ³€μˆ˜λ₯Ό λͺ…ν™•ν•˜κ²Œ μ‚¬μš©ν•©λ‹ˆλ‹€ i2.

μžμ‹ μ˜ μ‹œλ„λŠ” i(콜 μ‚¬μ΄νŠΈμ˜ λ²”μœ„μ—μžˆλŠ”) 읡λͺ… ν•¨μˆ˜μ— 인수둜 μ „λ‹¬ν•©λ‹ˆλ‹€. 이것은 μ§€κΈˆκΉŒμ§€μ˜ ν΄λ‘œμ €κ°€ μ•„λ‹ˆμ§€λ§Œ ν•΄λ‹Ή ν•¨μˆ˜λŠ” λ™μΌν•œλ₯Ό μ°Έμ‘°ν•˜λŠ” λ‹€λ₯Έ ν•¨μˆ˜λ₯Ό λ°˜ν™˜ν•©λ‹ˆλ‹€ i2. λ‚΄λΆ€ 읡λͺ… ν•¨μˆ˜ λ‚΄λΆ€ i2λŠ” 둜컬이 μ•„λ‹ˆλ―€λ‘œ ν΄λ‘œμ €κ°€ μƒμ„±λ©λ‹ˆλ‹€.


λ‹΅λ³€

λ‹Ήμ‹ κ³Ό λ‹Ήμ‹ μ˜ μΉœκ΅¬λŠ” λͺ¨λ‘ 폐쇄λ₯Ό μ‚¬μš©ν•©λ‹ˆλ‹€ :

ν΄λ‘œμ €λŠ” ν•¨μˆ˜μ™€ ν•΄λ‹Ή ν•¨μˆ˜κ°€ μž‘μ„±λœ ν™˜κ²½μ˜ 두 κ°€μ§€λ₯Ό κ²°ν•©ν•œ νŠΉλ³„ν•œ μ’…λ₯˜μ˜ κ°μ²΄μž…λ‹ˆλ‹€. ν™˜κ²½μ€ ν΄λ‘œμ €κ°€ 생성 될 λ•Œ λ²”μœ„ 내에 있던 둜컬 λ³€μˆ˜λ‘œ κ΅¬μ„±λ©λ‹ˆλ‹€.

MDN : https://developer.mozilla.org/en-US/docs/JavaScript/Guide/Closures

function(){ console.log(i2); }읡λͺ… ν•¨μˆ˜μ˜ 폐쇄 내뢀에 μ •μ˜ 된 친ꡬ의 μ½”λ“œ ν•¨μˆ˜μ—μ„œ function(){ var i2 = i; ...둜컬 λ³€μˆ˜λ₯Ό 읽고 μ“Έ 수 μžˆμŠ΅λ‹ˆλ‹€ i2.

μ½”λ“œ ν•¨μˆ˜μ—μ„œ ν•¨μˆ˜ function(){ console.log(i2); }폐쇄 내뢀에 μ •μ˜λ˜μ–΄ function(i2){ return ...있으며 둜컬 κ°€μΉ˜λ₯Ό μ½κ±°λ‚˜ μ“Έ 수 μžˆμŠ΅λ‹ˆλ‹€ i2(이 경우 맀개 λ³€μˆ˜λ‘œ μ„ μ–Έ).

두 경우 λͺ¨λ‘ ν•¨μˆ˜λŠ” function(){ console.log(i2); }둜 μ „λ‹¬λ©λ‹ˆλ‹€ setTimeout.

λ©”λͺ¨λ¦¬ μ‚¬μš©λŸ‰μ΄ 적은 λ‹€λ₯Έ 방법은 λ‹€μŒκ³Ό κ°™μŠ΅λ‹ˆλ‹€.

function fGenerator(i2){
    return function(){
        console.log(i2);
    }
}
for(var i = 0; i < 10; i++) {
    setTimeout(fGenerator(i), 1000);
}

λ‹΅λ³€

폐쇄

ν΄λ‘œμ €λŠ” ν•¨μˆ˜κ°€ μ•„λ‹ˆλ©° ν‘œν˜„μ‹μ΄ μ•„λ‹™λ‹ˆλ‹€. ν•¨μˆ˜ μŠ€μ½”ν”„ μ™ΈλΆ€μ—μ„œ μ‚¬μš© 된 λ³€μˆ˜μ™€ ν•¨μˆ˜ λ‚΄λΆ€μ—μ„œ μ‚¬μš©λ˜λŠ” μΌμ’…μ˜ β€˜μŠ€λƒ… μƒ·β€™μœΌλ‘œ ν‘œμ‹œλ˜μ–΄μ•Όν•©λ‹ˆλ‹€. λ¬Έλ²•μ μœΌλ‘œ, β€˜λ³€μˆ˜λ₯Ό λ‹«μŠ΅λ‹ˆλ‹€β€™λΌκ³  λ§ν•΄μ•Όν•©λ‹ˆλ‹€.

λ‹€μ‹œ λ§ν•˜λ©΄, ν΄λ‘œμ €λŠ” ν•¨μˆ˜κ°€ μ˜μ‘΄ν•˜λŠ” κ΄€λ ¨ λ³€μˆ˜ μ»¨ν…μŠ€νŠΈμ˜ λ³΅μ‚¬λ³Έμž…λ‹ˆλ‹€.

ν•œ 번 더 (naΓ―f) : ν΄λ‘œμ €κ°€ 맀개 λ³€μˆ˜λ‘œ μ „λ‹¬λ˜μ§€ μ•Šμ€ λ³€μˆ˜μ— μ•‘μ„ΈμŠ€ ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

이 κΈ°λŠ₯ κ°œλ…μ€ μ‚¬μš©ν•˜λŠ” ν”„λ‘œκ·Έλž˜λ° μ–Έμ–΄ / ν™˜κ²½μ— 따라 크게 λ‹¬λΌμ§‘λ‹ˆλ‹€. JavaScriptμ—μ„œ ν΄λ‘œμ €λŠ” μ–΄νœ˜ λ²”μœ„ (λŒ€λΆ€λΆ„μ˜ c μ–Έμ–΄μ—μ„œ 적용됨)에 μ˜μ‘΄ν•©λ‹ˆλ‹€.

λ”°λΌμ„œ ν•¨μˆ˜λ₯Ό λ°˜ν™˜ν•˜λŠ” 것은 λŒ€λΆ€λΆ„ 읡λͺ… / λͺ…λͺ…λ˜μ§€ μ•Šμ€ ν•¨μˆ˜λ₯Ό λ°˜ν™˜ν•©λ‹ˆλ‹€. ν•¨μˆ˜κ°€ λ³€μˆ˜λ‘œ μ•‘μ„ΈμŠ€ν•˜μ§€ μ•Šκ³  맀개 λ³€μˆ˜λ‘œ μ „λ‹¬λ˜μ§€ μ•Šκ³  (μ–΄νœ˜) λ²”μœ„ λ‚΄μ—μ„œ ν΄λ‘œμ €κ°€ λ°œμƒν–ˆμŠ΅λ‹ˆλ‹€.

λ”°λΌμ„œ κ·€ν•˜μ˜ μ˜ˆμ™€ κ΄€λ ¨ν•˜μ—¬ :

// 1
for(var i = 0; i < 10; i++) {
    setTimeout(function() {
        console.log(i); // closure, only when loop finishes within 1000 ms,
    }, 1000);           // i = 10 for all functions
}
// 2
for(var i = 0; i < 10; i++) {
    (function(){
        var i2 = i; // closure of i (lexical scope: for-loop)
        setTimeout(function(){
            console.log(i2); // closure of i2 (lexical scope:outer function)
        }, 1000)
    })();
}
// 3
for(var i = 0; i < 10; i++) {
    setTimeout((function(i2){
        return function() {
            console.log(i2); // closure of i2 (outer scope)

        }
    })(i), 1000); // param access i (no closure)
}

λͺ¨λ‘ 폐쇄λ₯Ό μ‚¬μš©ν•˜κ³  μžˆμŠ΅λ‹ˆλ‹€. μ‹€ν–‰ 지점과 ν΄λ‘œμ €λ₯Ό ν˜Όλ™ν•˜μ§€ λ§ˆμ‹­μ‹œμ˜€. ν΄λ‘œμ €μ˜ β€˜μŠ€λƒ… 샷’을 잘λͺ»λœ μˆœκ°„μ— κ°€μ Έ 였면 값이 μ˜ˆμƒμΉ˜ λͺ»ν•œ 것일 수 μžˆμ§€λ§Œ ν™•μ‹€νžˆ ν΄λ‘œμ €κ°€ λ°œμƒν•©λ‹ˆλ‹€!