본문으둜 κ±΄λ„ˆλ›°κΈ°

🌈 Chapter 2: μ‹€ν–‰ μ»¨ν…μŠ€νŠΈ

  • μ‹€ν–‰ μ»¨ν…μŠ€νŠΈ(execution context)λŠ” μ‹€ν–‰ν•  μ½”λ“œμ— μ œκ³΅ν•  ν™˜κ²½ 정보듀을 λͺ¨μ•„놓은 객체둜, μžλ°”μŠ€ν¬λ¦½νŠΈμ˜ 동적 μ–Έμ–΄λ‘œμ„œμ˜ 성격을 κ°€μž₯ 잘 νŒŒμ•…ν•  수 μžˆλŠ” κ°œλ…μ΄λ‹€.
  • μžλ°”μŠ€ν¬λ¦½νŠΈλŠ” μ–΄λ–€ μ‹€ν–‰ μ»¨ν…μŠ€νŠΈκ°€ ν™œμ„±ν™”λ˜λŠ” μ‹œμ μ— μ„ μ–Έλœ λ³€μˆ˜λ₯Ό μœ„λ‘œ λŒμ–΄μ˜¬λ¦¬κ³ (ν˜Έμ΄μŠ€νŒ…), μ™ΈλΆ€ ν™˜κ²½ 정보λ₯Ό κ΅¬μ„±ν•˜κ³ , this 값을 μ„€μ •ν•˜λŠ” λ“±μ˜ λ™μž‘μ„ μˆ˜ν–‰ν•œλ‹€.

πŸ“š μ‹€ν–‰ μ»¨ν…μŠ€νŠΈλž€?​

  • μ‹€ν–‰ μ»¨ν…μŠ€νŠΈ(execution context)λŠ” μ‹€ν–‰ν•  μ½”λ“œμ— μ œκ³΅ν•  ν™˜κ²½ 정보듀을 λͺ¨μ•„놓은 객체이닀.
  • λ™μΌν•œ ν™˜κ²½μ— μžˆλŠ” μ½”λ“œλ“€μ„ μ‹€ν–‰ν•  λ•Œ ν•„μš”ν•œ ν™˜κ²½ 정보듀을 λͺ¨μ•„ μ»¨ν…μŠ€νŠΈλ₯Ό κ΅¬μ„±ν•˜κ³ , 이λ₯Ό 콜 μŠ€νƒμ— μŒ“μ•„μ˜¬λ Έλ‹€κ°€, κ°€μž₯ μœ„μ— μŒ“μ—¬μžˆλŠ” μ»¨ν…μŠ€νŠΈμ™€ κ΄€λ ¨ μžˆλŠ” μ½”λ“œλ“€μ„ μ‹€ν–‰ν•˜λŠ” μ‹μœΌλ‘œ 전체 μ½”λ“œμ˜ ν™˜κ²½κ³Ό μˆœμ„œλ₯Ό 보μž₯ν•œλ‹€.
// μ‹€ν–‰ μ»¨ν…μŠ€νŠΈμ™€ 콜 μŠ€νƒ
// ------------------ (1)
var a = 1;
function outer() {
function inner() {
console.log(a); // undefined
var a = 3;
}

inner(); // ------------ (2)
console.log(a); // 1
}

outer(); // ------------ (3)
console.log(a); // 1
  1. μœ„ μ˜ˆμ œμ™€ 같이 처음 μžλ°”μŠ€ν¬λ¦½νŠΈ μ½”λ“œλ₯Ό μ‹€ν–‰ν•˜λŠ” μˆœκ°„ (1) μ „μ—­ μ»¨ν…μŠ€νŠΈκ°€ 콜 μŠ€νƒμ— λ‹΄κΈ΄λ‹€. μ΅œμƒλ‹¨μ˜ 곡간은 μ½”λ“œ λ‚΄λΆ€μ—μ„œ λ³„λ„μ˜ μ‹€ν–‰ λͺ…령이 없어도 λΈŒλΌμš°μ €μ—μ„œ μžλ™μœΌλ‘œ μ‹€ν–‰ν•˜λ―€λ‘œ μžλ°”μŠ€ν¬λ¦½νŠΈ 파일이 μ—΄λ¦¬λŠ” μˆœκ°„ μ „μ—­ μ»¨ν…μŠ€νŠΈκ°€ ν™œμ„±ν™”λœλ‹€.
  2. 콜 μŠ€νƒμ—λŠ” μ „μ—­ μ»¨ν…μŠ€νŠΈ 외에 λ‹€λ₯Έ 덩어리가 μ—†μœΌλ―€λ‘œ μ „μ—­ μ»¨ν…μŠ€νŠΈμ™€ κ΄€λ ¨λœ μ½”λ“œλ“€μ„ 순차둜 μ§„ν–‰ν•˜λ‹€κ°€ (3)μ—μ„œ outer ν•¨μˆ˜λ₯Ό ν˜ΈμΆœν•˜λ©΄ μžλ°”μŠ€ν¬λ¦½νŠΈ 엔진은 outer에 λŒ€ν•œ ν™˜κ²½ 정보λ₯Ό μˆ˜μ§‘ν•΄μ„œ outer μ‹€ν–‰ μ»¨ν…μŠ€νŠΈλ₯Ό μƒμ„±ν•œ ν›„ 콜 μŠ€νƒμ— λ‹΄λŠ”λ‹€.
  3. 콜 μŠ€νƒμ˜ 맨 μœ„μ— outer μ‹€ν–‰ μ»¨ν…μŠ€νŠΈκ°€ 놓인 μƒνƒœκ°€ λμœΌλ―€λ‘œ μ „μ—­ μ»¨ν…μŠ€νŠΈμ™€ κ΄€λ ¨λœ μ½”λ“œμ˜ 싀행을 μΌμ‹œ μ€‘λ‹¨ν•˜κ³  λŒ€μ‹  outer μ‹€ν–‰ μ»¨ν…μŠ€νŠΈμ™€ κ΄€λ ¨λœ μ½”λ“œ, 즉 outer ν•¨μˆ˜ λ‚΄λΆ€μ˜ μ½”λ“œλ“€μ„ 순차적으둜 μ‹€ν–‰ν•œλ‹€.
  4. λ‹€μ‹œ (2)μ—μ„œ inner ν•¨μˆ˜μ˜ μ‹€ν–‰ μ»¨ν…μŠ€νŠΈκ°€ 콜 μŠ€νƒμ˜ κ°€μž₯ μœ„μ— λ‹΄κΈ°λ©΄ outer μ»¨ν…μŠ€νŠΈμ™€ κ΄€λ ¨λœ μ½”λ“œμ˜ 싀행을 μ€‘λ‹¨ν•˜κ³  inner ν•¨μˆ˜ λ‚΄λΆ€μ˜ μ½”λ“œλ₯Ό μˆœμ„œλŒ€λ‘œ μ§„ν–‰ν•œλ‹€.
  5. inner ν•¨μˆ˜ λ‚΄λΆ€μ—μ„œ a λ³€μˆ˜μ— κ°’ 3을 ν• λ‹Ήν•˜κ³  λ‚˜λ©΄ inner ν•¨μˆ˜μ˜ 싀행이 μ’…λ£Œλ˜λ©΄μ„œ inner μ‹€ν–‰ μ»¨ν…μŠ€νŠΈκ°€ 콜 μŠ€νƒμ—μ„œ μ œκ±°λœλ‹€. κ·Έ ν›„ (2)의 λ‹€μŒ 쀄뢀터 μ΄μ–΄μ„œ μ‹€ν–‰ν•œλ‹€.
  6. a λ³€μˆ˜μ˜ 값을 좜λ ₯ν•˜κ³  λ‚˜λ©΄ outer ν•¨μˆ˜μ˜ 싀행이 μ’…λ£Œλ˜μ–΄ outer μ‹€ν–‰ μ»¨ν…μŠ€νŠΈκ°€ 콜 μŠ€ν…μ—μ„œ 제거되고 클 μŠ€νƒμ—λŠ” μ „μ—­ μ»¨ν…μŠ€νŠΈλ§Œ 남아 있게 λœλ‹€.
  7. 그런 λ‹€μŒ, 싀행을 μ€‘λ‹¨ν–ˆλ˜ (3)의 λ‹€μŒ 쀄뢀터 μ΄μ–΄μ„œ μ‹€ν–‰ν•œλ‹€. a λ³€μˆ˜μ˜ 값을 좜λ ₯ν•˜κ³  λ‚˜λ©΄ μ „μ—­ 곡간에 λ”λŠ” μ‹€ν–‰ν•  μ½”λ“œκ°€ 남아 μžˆμ§€ μ•Šμ•„ μ „μ—­ μ»¨ν…μŠ€νŠΈλ„ 제거되고, 콜 μŠ€νƒμ—λŠ” 아무것도 남지 μ•Šμ€ μƒνƒœλ‘œ μ’…λ£Œλ˜κ²Œ λœλ‹€.
  • μ΄λ ‡κ²Œ μ–΄λ–€ μ‹€ν–‰ μ»¨ν…μŠ€νŠΈκ°€ ν™œμ„±ν™”λ  λ•Œ μžλ°”μŠ€ν¬λ¦½νŠΈ 엔진은 ν•΄λ‹Ή μ»¨ν…μŠ€νŠΈμ— κ΄€λ ¨λœ μ½”λ“œλ“€μ„ μ‹€ν–‰ν•˜λŠ” 데 ν•„μš”ν•œ ν™˜κ²½ 정보듀을 μˆ˜μ§‘ν•΄μ„œ μ‹€ν–‰ μ»¨ν…μŠ€νŠΈ 객체에 μ €μž₯ν•œλ‹€. 이 κ°μ²΄λŠ” μžλ°”μŠ€ν¬λ¦½νŠΈ 엔진이 ν™œμš©ν•  λͺ©μ μœΌλ‘œ 생성할 λΆ„ κ°œλ°œμžκ°€ μ½”λ“œλ₯Ό 톡해 확인할 수 μ—†λ‹€. 여기에 λ‹΄κΈ°λŠ” 정보듀은 λ‹€μŒκ³Ό κ°™λ‹€.
    • VariableEnvironment: ν˜„μž¬ μ»¨ν…μŠ€νŠΈ λ‚΄μ˜ μ‹λ³„μžλ“€μ— λŒ€ν•œ 정보 + μ™ΈλΆ€ ν™˜κ²½ 정보. μ„ μ–Έ μ‹œμ μ˜ LexicalEnvironment의 μŠ€λƒ…μƒ·μœΌλ‘œ, λ³€κ²½ 사항은 λ°˜μ˜λ˜μ§€ μ•ŠμŒ.
    • LexicalEnvironment: μ²˜μŒμ—λŠ” VariableEnvironment와 κ°™μ§€λ§Œ λ³€κ²½ 사항이 μ‹€μ‹œκ°„μœΌλ‘œ 반영됨.
    • ThisBinding: this μ‹λ³„μžκ°€ 바라봐야 ν•  λŒ€μƒ 객체.

πŸ“š VariableEnvironment​

  • VariableEnvironment에 λ‹΄κΈ°λŠ” λ‚΄μš©μ€ LexicalEnvironment와 κ°™μ§€λ§Œ 졜초 μ‹€ν–‰ μ‹œμ˜ μŠ€λƒ…μƒ·μ„ μœ μ§€ν•œλ‹€λŠ” 점이 λ‹€λ₯΄λ‹€.
  • μ‹€ν–‰ μ»¨ν…μŠ€νŠΈλ₯Ό 생성할 λ•Œ VariableEnvironment에 정보λ₯Ό λ¨Όμ € 담은 λ‹€μŒ, 이λ₯Ό κ·ΈλŒ€λ‘œ λ³΅μ‚¬ν•΄μ„œ LexicalEnvironmentλ₯Ό λ§Œλ“€κ³ , μ΄ν›„μ—λŠ” LexicalEnvironmentλ₯Ό 주둜 ν™œμš©ν•œλ‹€.
  • VariableEnvironment와 LexicalEnvironment의 λ‚΄λΆ€λŠ” environmentRecord와 outerEnvironmentReference둜 ꡬ성돼 μžˆλ‹€.

πŸ“š LexicalEnvironment​

🎈 environmentRecord와 ν˜Έμ΄μŠ€νŒ…β€‹

  • environmentRecordμ—λŠ” ν˜„μž¬ μ»¨ν…μŠ€νŠΈμ™€ κ΄€λ ¨λœ μ½”λ“œμ˜ μ‹λ³„μž 정보듀이 μ €μž₯λœλ‹€. μ»¨ν…μŠ€νŠΈλ₯Ό κ΅¬μ„±ν•˜λŠ” ν•¨μˆ˜μ— μ§€μ •λœ λ§€κ°œλ³€μˆ˜ μ‹λ³„μž, μ„ μ–Έν•œ ν•¨μˆ˜κ°€ μžˆμ„ 경우 κ·Έ ν•¨μˆ˜ 자체, var둜 μ„ μ–Έλœ λ³€μˆ˜μ˜ μ‹λ³„μž 등이 μ‹λ³„μžμ— ν•΄λ‹Ήν•œλ‹€. μ»¨ν…μŠ€νŠΈ λ‚΄λΆ€ 전체λ₯Ό μ²˜μŒλΆ€ν„° λκΉŒμ§€ μ­‰ ν›‘μ–΄λ‚˜κ°€λ©° μˆœμ„œλŒ€λ‘œ μˆ˜μ§‘ν•œλ‹€.
  • μ½”λ“œκ°€ μ‹€ν–‰λ˜κΈ° μ „μž„μ—λ„ λΆˆκ΅¬ν•˜κ³  μžλ°”μŠ€ν¬λ¦½νŠΈ 엔진은 이미 ν•΄λ‹Ή ν™˜κ²½μ— μ†ν•œ μ½”λ“œμ˜ λ³€μˆ˜λͺ…듀을 λͺ¨λ‘ μ•Œκ³  있게 λœλ‹€. κ·Έ 말은 즉, μžλ°”μŠ€ν¬λ¦½νŠΈ 엔진은 μ‹λ³„μžλ“€μ„ μ΅œμƒλ‹¨μœΌλ‘œ λŒμ–΄μ˜¬λ €λ†“μ€ λ‹€μŒ μ‹€μ œ μ½”λ“œλ₯Ό μ‹€ν–‰ν•œλ‹€λΌκ³  생각해도 문제 μ—†λ‹€. μ—¬κΈ°μ„œ ν˜Έμ΄μŠ€νŒ…μ΄λΌλŠ” κ°œλ…μ΄ λ“±μž₯ν•œλ‹€.

🐢 ν˜Έμ΄μŠ€νŒ… κ·œμΉ™β€‹

  • environmentRecordμ—λŠ” λ§€κ°œλ³€μˆ˜, 이름, ν•¨μˆ˜ μ„ μ–Έ, λ³€μˆ˜λͺ… 등이 λ‹΄κΈ΄λ‹€.
// λ§€κ°œλ³€μˆ˜μ™€ λ³€μˆ˜μ— λŒ€ν•œ ν˜Έμ΄μŠ€νŒ…
function a() {
var x = 1; // μˆ˜μ§‘ λŒ€μƒ 1(λ§€κ°œλ³€μˆ˜ μ„ μ–Έ)
console.log(x); // (1)
var x; // μˆ˜μ§‘ λŒ€μƒ 2(λ³€μˆ˜ μ„ μ–Έ)
console.log(x); // (2)
var x = 2; // μˆ˜μ§‘ λŒ€μƒ 3(λ³€μˆ˜ μ„ μ–Έ)
console.log(x); // (3)
}

a();
  • environmentRecordλŠ” ν˜„μž¬ 싀행될 μ»¨ν…μŠ€νŠΈμ˜ λŒ€μƒ μ½”λ“œ 내에 μ–΄λ–€ μ‹λ³„μžλ“€μ΄ μžˆλŠ”μ§€μ—λ§Œ 관심이 있고, 각 μ‹λ³„μžμ— μ–΄λ–€ 값이 할당될 κ²ƒμΈμ§€λŠ” 관심이 μ—†λ‹€. λ”°λΌμ„œ λ³€μˆ˜λ₯Ό ν˜Έμ΄μŠ€νŒ…ν•  λ•Œ λ³€μˆ˜λͺ…λ§Œ λŒμ–΄μ˜¬λ¦¬κ³  ν• λ‹Ή 과정은 μ›λž˜ μžλ¦¬μ— κ·Έλž˜λ„ 남겨둔닀. λ§€κ°œλ³€μˆ˜μ˜ κ²½μš°μ—λ„ λ§ˆμ°¬κ°€μ§€μ΄λ‹€.
  • environmentRecord의 관심사에 맞좰 μˆ˜μ§‘ λŒ€μƒ 1, 2, 3을 μˆœμ„œλŒ€λ‘œ λŒμ–΄μ˜¬λ¦¬κ³  λ‚˜λ©΄ λ‹€μŒκ³Ό 같은 ν˜•νƒœλ‘œ 바뀐닀.
function a() {
var x; // μˆ˜μ§‘ λŒ€μƒ 1의 λ³€μˆ˜ μ„ μ–Έ λΆ€λΆ„
var x; // μˆ˜μ§‘ λŒ€μƒ 2의 λ³€μˆ˜ μ„ μ–Έ λΆ€λΆ„
var x; // μˆ˜μ§‘ λŒ€μƒ 3의 λ³€μˆ˜ μ„ μ–Έ λΆ€λΆ„

x = 1; // μˆ˜μ§‘ λŒ€μƒ 1의 ν• λ‹Ή λΆ€λΆ„
console.log(x); // (1)
console.log(x); // (2)
x = 2; // μˆ˜μ§‘ λŒ€μƒ 3의 ν• λ‹Ή λΆ€λΆ„
console.log(x); // (3)
}

a(1);
  • 이제 ν˜Έμ΄μŠ€νŒ…μ΄ λλ‚¬μœΌλ‹ˆ μ‹€μ œ μ½”λ“œκ°€ 싀행될 차둀이닀.
    1. λ³€μˆ˜ xλ₯Ό μ„ μ–Έν•˜κ³  μ΄λ•Œ λ©”λͺ¨λ¦¬μ—μ„œλŠ” μ €μž₯ν•  곡간을 미리 ν™•λ³΄ν•˜κ³ , ν™•λ³΄ν•œ κ³΅κ°„μ˜ μ£Όμ†Ÿκ°’μ„ λ³€μˆ˜ x에 μ—°κ²°ν•΄λ‘”λ‹€.
    2. κ·Έ λ‹€μŒ λ³€μˆ˜ xλ₯Ό μ°¨λ‘€λ‘œ μ„ μ–Έν•œλ‹€. 이미 μ„ μ–Έλœ λ³€μˆ˜ xκ°€ μ‘΄μž¬ν•˜λ‹ˆ λ¬΄μ‹œν•œλ‹€.
    3. x에 1을 ν• λ‹Ήν•œλ‹€. μš°μ„  숫자 1을 λ³„λ„μ˜ λ©”λͺ¨λ¦¬μ— λ‹΄κ³ , x와 μ—°κ²°λœ λ©”λͺ¨λ¦¬ 곡간에 숫자 1을 κ°€λ¦¬ν‚€λŠ” μ£Όμ†Ÿκ°’μ„ μž…λ ₯ν•œλ‹€.
    4. xλ₯Ό (1)κ³Ό (2)μ—μ„œ 1이 좜λ ₯λœλ‹€.
    5. x에 2λ₯Ό ν• λ‹Ήν•œλ‹€. 숫자 2λ₯Ό λ³„λ„μ˜ λ©”λͺ¨λ¦¬μ— λ‹΄κ³ , κ·Έ μ£Όμ†Ÿκ°’μ„ λ“  μ±„λ‘œ x와 μ—°κ²°λœ λ©”λͺ¨λ¦¬ κ³΅κ°„μœΌλ‘œ κ°„λ‹€. 이제 λ³€μˆ˜ xλŠ” 숫자 2λ₯Ό κ°€λ¦¬ν‚€κ²Œ λœλ‹€.
    6. xκ°€ (3)μ—μ„œ 2κ°€ 좜λ ₯되고, 이제 ν•¨μˆ˜ λ‚΄λΆ€μ˜ λͺ¨λ“  μ½”λ“œκ°€ μ‹€ν–‰λμœΌλ―€λ‘œ μ‹€ν–‰ μ»¨ν…μŠ€νŠΈκ°€ 콜 μŠ€νƒμ—μ„œ μ œκ±°λœλ‹€.
// ν•¨μˆ˜ μ„ μ–Έμ˜ ν˜Έμ΄μŠ€νŒ…
function a() {
console.log(b); // (1)
var b = 'bbb'; // μˆ˜μ§‘ λŒ€μƒ 1(λ³€μˆ˜ μ„ μ–Έ)
console.log(b); // (2)
function b () {} // μˆ˜μ§‘ λŒ€μƒ 2(ν•¨μˆ˜ μ„ μ–Έ)
console.log(b); // (3)
}

a();
  • a ν•¨μˆ˜λ₯Ό μ‹€ν–‰ν•˜λŠ” μˆœκ°„ a ν•¨μˆ˜μ˜ μ‹€ν–‰ μ»¨ν…μŠ€νŠΈκ°€ μƒμ„±λœλ‹€. μ΄λ•Œ λ³€μˆ˜λͺ…κ³Ό ν•¨μˆ˜ μ„ μ–Έμ˜ 정보λ₯Ό μœ„λ‘œ λŒμ–΄μ˜¬λ¦°λ‹€. λ³€μˆ˜λŠ” 선언뢀와 ν• λ‹ΉλΆ€λ₯Ό λ‚˜λˆ„μ–΄ μ„ μ–ΈλΆ€λ§Œ λŒμ–΄μ˜¬λ¦¬λŠ” 반면 ν•¨μˆ˜ 선언은 ν•¨μˆ˜ 전체λ₯Ό λŒμ–΄μ˜¬λ¦°λ‹€.
function a() {
var b; // μˆ˜μ§‘ λŒ€μƒ 1. λ³€μˆ˜λŠ” μ„ μ–ΈλΆ€λ§Œ λŒμ–΄μ˜¬λ¦°λ‹€.
function b() {} // μˆ˜μ§‘ λŒ€μƒ2. ν•¨μˆ˜ 선언은 전체λ₯Ό λŒμ–΄μ˜¬λ¦°λ‹€.

console.log(b); // (1)
b = 'bbb'; // λ³€μˆ˜μ˜ ν• λ‹ΉλΆ€λŠ” μ›λž˜ μžλ¦¬μ— 남겨둔닀.
console.log(b); // (2)
console.log(b); // (3)
}

a();

🐢 ν•¨μˆ˜ μ„ μ–Έλ¬Έκ³Ό ν•¨μˆ˜ ν‘œν˜„μ‹β€‹

  • ν•¨μˆ˜ 선언문은 function μ •μ˜λΆ€λ§Œ μ‘΄μž¬ν•˜κ³  λ³„λ„μ˜ ν• λ‹Ή λͺ…령이 μ—†λŠ” 것을 μ˜λ―Έν•˜κ³ , λ°˜λŒ€λ‘œ ν•¨μˆ˜ ν‘œν˜„μ‹μ€ μ •μ˜ν•œ function을 λ³„λ„μ˜ λ³€μˆ˜μ— ν• λ‹Ήν•˜λŠ” 것을 λ§ν•œλ‹€.
function a() { /* ... */} // ν•¨μˆ˜ μ„ μ–Έλ¬Έ.

var b = function () { /* ... */} // (읡λͺ…) ν•¨μˆ˜ ν‘œν˜„μ‹

var c = function d() { /* ... */} // κΈ°λͺ… ν•¨μˆ˜ ν‘œν˜„μ‹, ν•¨μˆ˜λͺ…μœΌλ‘œλŠ” 호좜 λΆˆκ°€
  • ν•¨μˆ˜ μ„ μ–Έλ¬Έκ³Ό ν•¨μˆ˜ ν‘œν˜„μ‹
console.log(sum(1, 2));
console.log(multiply(3, 4));

function sum (a, b) { // ν•¨μˆ˜ μ„ μ–Έλ¬Έ sum
return a + b;
}

var multiply = function (a, b) { // ν•¨μˆ˜ ν‘œν˜„μ‹ multiply
return a * b;
}
  • λ‹€μŒμ€ μœ„ μ½”λ“œκ°€ ν˜Έμ΄μŠ€νŒ…μ„ 마친 μƒνƒœμ΄λ‹€.
var sum = function sum(a, b) { // ν•¨μˆ˜ 선언문은 전체λ₯Ό ν˜Έμ΄μŠ€νŒ…μ΄ν•œλ‹€.
return a + b;
};

var multiply; // λ³€μˆ˜λŠ” μ„ μ–ΈλΆ€λ§Œ λŒμ–΄μ˜¬λ¦°λ‹€.

console.log(sum(1, 2)); // 3
console.log(multiply(3, 4)); // multiply is not a function.

multiply = function (a, b) { // λ³€μˆ˜μ˜ ν• λ‹ΉλΆ€λŠ” μ›λž˜ μžλ¦¬μ—..
return a * b;
}
  • μœ„ μ˜ˆμ—μ„œ multiply ν˜ΈμΆœμ‹œ 값이 할당돼 μžˆμ§€ μ•Šλ‹€. λΉ„μ–΄μžˆλŠ” λŒ€μƒμ„ ν•¨μˆ˜λ‘œ 여겨 μ‹€ν–‰ν•˜λΌκ³  λͺ…λ Ήν–ˆλ‹€. λ”°λΌμ„œ multiply us not a functionμ΄λΌλŠ” μ—λŸ¬ λ©”μ‹œμ§€κ°€ 좜λ ₯λœλ‹€.

🎈 μŠ€μ½”ν”„, μŠ€μ½”ν”„ 체인, outerEnvironmentReference​

  • μŠ€μ½”ν”„(scope)λž€ μ‹λ³„μžμ— λŒ€ν•œ μœ νš¨λ²”μœ„μ΄λ‹€.
  • μ–΄λ–€ 경계 A의 μ™ΈλΆ€μ—μ„œ μ„ μ–Έν•œ λ³€μˆ˜λŠ” A의 외뢀뿐 μ•„λ‹ˆλΌ A의 λ‚΄λΆ€μ—μ„œλ„ 접근이 κ°€λŠ₯ν•˜μ§€λ§Œ, A의 λ‚΄λΆ€μ—μ„œ μ„ μ–Έν•œ λ³€μˆ˜λŠ” 였직 A의 λ‚΄λΆ€μ—μ„œλ§Œ μ ‘κ·Όν•  수 μžˆλ‹€.
  • μ‹λ³„μžμ˜ μœ νš¨λ²”μœ„λ₯Ό μ•ˆμ—μ„œλΆ€ν„° λ°”κΉ₯으둜 μ°¨λ‘€λ‘œ κ²€μƒ‰ν•΄λ‚˜κ°€λŠ” 것을 μŠ€μ½”ν”„ 체인(scope chain)이라고 ν•œλ‹€. 그리고 이λ₯Ό κ°€λŠ₯μΌ€ ν•˜λŠ” 것이 λ°”λ‘œ LexicalEnvironment의 두 번째 μˆ˜μ§‘ 자료인 outerEnvironmentReference이닀.

🐢 μŠ€μ½”ν”„ 체인​

  • outerEnvironmentReferenceλŠ” ν˜„μž¬ 호좜된 ν•¨μˆ˜κ°€ 선언될 λ‹Ήμ‹œμ˜ LexicalEnvironmentλ₯Ό μ°Έμ‘°ν•œλ‹€.
  • 예λ₯Ό λ“€μ–΄, Aν•¨μˆ˜ 내뢀에 B ν•¨μˆ˜λ₯Ό μ„ μ–Έν•˜κ³  λ‹€μ‹œ B ν•¨μˆ˜ 내뢀에 C ν•¨μˆ˜λ₯Ό μ„ μ–Έν•œ 경우, ν•¨μˆ˜ C의 outerEnvironmentReferenceλŠ” ν•¨μˆ˜ B의 LexicalEnvironmentλ₯Ό μ°Έμ‘°ν•œλ‹€. ν•¨μˆ˜ B의 LexicalEnvironment에 μžˆλŠ” outerEnvironmentReferenceλŠ” λ‹€μ‹œ ν•¨μˆ˜ Bκ°€ μ„ μ–Έλ˜λ˜ λ•Œ(A)의 LexicalEnvironmentλ₯Ό μ°Έμ‘°ν•œλ‹€.
  • 이처럼 outerEnvironmentReferenceλŠ” μ—°κ²°λ¦¬μŠ€νŠΈ ν˜•νƒœλ₯Ό 띀닀. μ„ μ–Έ μ‹œμ μ˜ LexicalEnvironmentλ₯Ό 계속 μ°Ύμ•„ μ˜¬λΌκ°€λ©΄ λ§ˆμ§€λ§‰μ—” μ „μ—­ μ»¨ν…μŠ€νŠΈμ˜ LexicalEnvironmentκ°€ μžˆμ„ 것이닀. λ˜ν•œ 각 outerEnvironmentReferenceλŠ” 였직 μžμ‹ μ΄ μ„ μ–Έλœ μ‹œμ μ˜ LexicalEnvironment만 μ°Έμ‘°ν•˜κ³  μžˆμœΌλ―€λ‘œ κ°€μž₯ κ°€κΉŒμš΄ μš”μ†ŒλΆ€ν„° μ°¨λ‘€λŒ€λ‘œλ§Œ μ ‘κ·Όν•  수 있고 λ‹€λ₯Έ μˆœμ„œλ‘œλŠ” μ ‘κ·Όν•˜λŠ” 것은 λΆˆκ°€λŠ₯ν•˜λ‹€.
  • 이런 ꡬ쑰적 νŠΉμ„± 덕뢄에 μ—¬λŸ¬ μŠ€μ½”ν”„μ—μ„œ λ™μΌν•œ μ‹λ³„μžλ₯Ό μ„ μ–Έν•˜λŠ” κ²½μš°μ—λŠ” 무쑰건 μŠ€μ½”ν”„ 체인 μƒμ—μ„œ κ°€μž₯ λ¨Όμ € 발견된 μ‹λ³„μžμ—λ§Œ 접근이 κ°€λŠ₯ν•˜κ²Œ λ˜λŠ”κ²ƒμ΄λ‹€.
// μŠ€μ½”ν”„ 체인
var a = 1;
var outer = function () {
var inner = function () {
console.log(a);
var a = 3;
};

inner();
console.log(a);
};

outer();
console.log(a);
  1. μ „μ—­ μ»¨ν…μŠ€νŠΈκ°€ ν™œμ„±ν™”λœλ‹€. μ „μ—­ μ»¨ν…μŠ€νŠΈμ˜ environmentRecord에 {a, outer} μ‹λ³„μžλ₯Ό μ €μž₯ν•œλ‹€. μ „μ—­ μ»¨ν…μŠ€νŠΈλŠ” μ„ μ–Έ μ‹œμ μ΄ μ—†μœΌλ―€λ‘œ μ „μ—­ μ»¨ν…μŠ€νŠΈμ˜ outerEnvironmentReferenceμ—λŠ” 아무것도 담기지 μ•ŠλŠ”λ‹€. (this: μ „μ—­ 객체)
  2. μ „μ—­ μŠ€μ½”ν”„μ— μžˆλŠ” λ³€μˆ˜ a에 1을, outer에 ν•¨μˆ˜λ₯Ό ν• λ‹Ήν•œλ‹€.
  3. outer ν•¨μˆ˜λ₯Ό ν˜ΈμΆœν•œλ‹€. 이에 따라 μ „μ—­ μ»¨ν…μŠ€νŠΈμ˜ μ½”λ“œλŠ” outer ν˜ΈμΆœν•˜λŠ” μ‹œμ μ—μ„œ μž„μ‹œμ€‘λ‹¨λ˜κ³ , outer μ‹€ν–‰ μ»¨ν…μŠ€νŠΈκ°€ ν™œμ„±ν™”λ˜μ–΄ outer λ‚΄λΆ€μ˜ 첫번째 μ€„λ‘œ μ΄λ™ν•œλ‹€.
  4. outer μ‹€ν–‰ μ»¨ν…μŠ€νŠΈμ˜ environmentRecord에 { inner } μ‹λ³„μžλ₯Ό μ €μž₯ν•œλ‹€. outerEnvironmentReferenceμ—λŠ” outer ν•¨μˆ˜κ°€ 선언될 λ‹Ήμ‹œμ˜ LexicalEnvironmentκ°€ λ‹΄κΈ΄λ‹€. outer ν•¨μˆ˜λŠ” μ „μ—­ κ³΅κ°„μ—μ„œ μ„ μ–ΈλμœΌλ―€λ‘œ μ „μ—­ μ»¨ν…μŠ€νŠΈμ˜ LexicalEnvironmentλ₯Ό μ°Έμ‘°λ³΅μ‚¬ν•œλ‹€. 이λ₯Ό [GLOBAL, { a, outer }]라고 ν‘œκΈ°ν•œλ‹€. 첫 λ²ˆμ§ΈλŠ” μ‹€ν–‰ μ»¨ν…μŠ€νŠΈμ˜ 이름, 두 λ²ˆμ§ΈλŠ” environmentRecord 객체이닀. (this: μ „μ—­ 객체)
  5. outer μŠ€μ½”ν”„μ— μžˆλŠ” λ³€μˆ˜ inner에 ν•¨μˆ˜λ₯Ό ν• λ‹Ήν•œλ‹€.
  6. inner ν•¨μˆ˜λ₯Ό ν˜ΈμΆœν•˜κ³  이에 따라 outer μ‹€ν–‰ μ»¨ν…μŠ€νŠΈμ˜ μ½”λ“œλŠ” μž„μ‹œμ€‘λ‹¨λ˜κ³ , inner μ‹€ν–‰ μ»¨ν…μŠ€νŠΈκ°€ ν™œμ„±ν™”λ˜μ–΄ inner ν•¨μˆ˜ λ‚΄λΆ€μ˜ 첫 λ²ˆμ§Έμ€„λ‘œ μ΄λ™ν•œλ‹€.
  7. inner μ‹€ν–‰ μ»¨ν…μŠ€νŠΈμ˜ environmentRecord에 { a } μ‹λ³„μžλ₯Ό μ €μž₯ν•œλ‹€. outerEnvironmentReferenceμ—λŠ” inner ν•¨μˆ˜κ°€ 선언될 λ‹Ήμ‹œμ˜ LexicalEnvironmentκ°€ λ‹΄κΈ΄λ‹€. inner ν•¨μˆ˜λŠ” outer ν•¨μˆ˜ λ‚΄λΆ€μ—μ„œ μ„ μ–ΈλμœΌλ―€λ‘œ outer ν•¨μˆ˜μ˜ LexicalEnvironment 즉, [ outer, { inner }]λ₯Ό μ°Έμ‘°λ³΄κ³ μ‚¬ν•œλ‹€. (this: μ „μ—­ 객체)
  8. μ‹λ³„μž a에 μ ‘κ·Όν•˜κ³  ν˜„μž¬ ν™œμ„±ν™” μƒνƒœμΈ inner μ»¨ν…μŠ€νŠΈμ˜ environmentRecordμ—μ„œ aλ₯Ό κ²€μƒ‰ν•œλ‹€. aκ°€ λ°œκ²¬λλŠ”λ° 아직 ν• λ‹Ήλœ 값이 μ—†λ‹€. (undefined 좜λ ₯)
  9. inner μŠ€μ½”ν”„μ— μžˆλŠ” λ³€μˆ˜ a에 3을 ν• λ‹Ήν•œλ‹€.
  10. inner ν•¨μˆ˜ 싀행이 μ’…λ£Œλ˜κ³  inner μ‹€ν–‰ μ»¨ν…μŠ€νŠΈκ°€ 콜 μŠ€νƒμ—μ„œ 제거되고, λ°”λ‘œ μ•„λž˜μ˜ outer μ‹€ν–‰ μ»¨ν…μŠ€νŠΈκ°€ λ‹€μ‹œ ν™œμ„±ν™”λ˜λ©΄μ„œ, μ•žμ„œ μ€‘λ‹¨ν–ˆλ˜ inner 호좜 쀄 λ‹€μŒ μ€„λ‘œ μ΄λ™ν•œλ‹€.
  11. outer λ‚΄λΆ€μ˜ console.log(a) 즉, μ‹λ³„μž a에 μ ‘κ·Όν•˜κ³ μž ν•œλ‹€. μ΄λ•Œ μžλ°”μŠ€ν¬λ¦½νŠΈ 엔진은 ν™œμ„±ν™”λœ μ‹€ν–‰ μ»¨ν…μŠ€νŠΈμ˜ LexicalEnvironment에 μ ‘κ·Όν•œλ‹€. 첫 μš”μ†Œμ˜ environmentRecordμ—μ„œ aκ°€ μžˆλŠ”μ§€ 찾아보고, μ—†μœΌλ©΄ outerEnvironmentReference에 μžˆλŠ” environmentRecord둜 λ„˜μ–΄κ°€λŠ” μ‹μœΌλ‘œ κ³„μ†ν•΄μ„œ κ²€μƒ‰ν•œλ‹€. μ˜ˆμ œμ—μ„œλŠ” 두 번째 즉, μ „μ—­ LexicalEnvironment에 aκ°€ μžˆμœΌλ‹ˆ a에 μ €μž₯된 κ°’ 1을 λ°˜ν™˜ν•œλ‹€. (1 좜λ ₯)
  12. outer ν•¨μˆ˜ 싀행이 μ’…λ£Œλœλ‹€. outer μ‹€ν–‰ μ»¨ν…μŠ€νŠΈκ°€ 콜 μŠ€νƒμ—μ„œ 제거되고, λ°”λ‘œ μ•„λž˜ μ „μ—­ μ»¨ν…μŠ€νŠΈκ°€ λ‹€μ‹œ ν™œμ„±ν™”λ˜λ©΄μ„œ, μ•žμ„œ μ€‘λ‹¨ν–ˆλ˜ outer 호좜 λΆ€λΆ„ λ‹€μŒ μ€„λ‘œ μ΄λ™ν•œλ‹€.
  13. μ‹λ³„μž a에 μ ‘κ·Όν•˜κ³ μž ν•œλ‹€. ν˜„μž¬ ν™œμ„±ν™” μƒνƒœμΈ μ „μ—­ μ»¨νƒμŠ€νŠΈμ˜ environmentRecordμ—μ„œ aλ₯Ό κ²€μƒ‰ν•œλ‹€. λ°”λ‘œ aλ₯Ό μ°Ύκ³  (1 좜λ ₯) λͺ¨λ“  μ½”λ“œμ˜ 싀행이 μ™„λ£Œλœλ‹€.
  14. μ „μ—­ μ»¨ν…μŠ€νŠΈκ°€ 콜 μŠ€νƒμ—μ„œ 제거되고 μ’…λ£Œλœλ‹€.
  • μ „μ—­ κ³΅κ°„μ—μ„œλŠ” μ „μ—­ μŠ€μ½”ν”„μ—μ„œ μƒμ„±λœ λ³€μˆ˜λ§Œ μ ‘κ·Όν•  수 μžˆμ§€λ§Œ outer ν•¨μˆ˜ λ‚΄λΆ€μ—μ„œλŠ” outer 및 μ „μ—­ μŠ€μ½”ν”„μ—μ„œ μƒμ„±λœ λ³€μˆ˜μ— μ ‘κ·Όν•  수 μžˆλ‹€. λ˜ν•œ inner ν•¨μˆ˜ λ‚΄λΆ€μ—μ„œλŠ” inner, outer, μ „μ—­ μŠ€μ½”ν”„ λͺ¨λ‘μ— μ ‘κ·Όν•  수 μžˆλ‹€.
  • μŠ€μ½”ν”„ 체인 상에 μžˆλŠ” λ³€μˆ˜λΌκ³  ν•΄μ„œ 무쑰건 μ ‘κ·Ό κ°€λŠ₯ν•œ 건 μ•„λ‹Œλ° μœ„ μ½”λ“œμ—μ„œ μ‹λ³„μž aλŠ” μ „μ—­ κ³΅κ°„μ—μ„œλ„ μ„ μ–Έν–ˆκ³  inner ν•¨μˆ˜ λ‚΄λΆ€μ—μ„œ μ„ μ–Έν–ˆλ‹€. μ΄λ•Œ inner μŠ€μ½”ν”„μ˜ LexicalEnvironmentλΆ€ν„° 검색할 μˆ˜λ°–μ— μ—†κΈ° λ•Œλ¬Έμ— inner LexicalEnvironment에 a μ‹λ³„μžκ°€ μ‘΄μž¬ν•˜λ―€λ‘œ μŠ€μ½”ν”„ 체인 검색을 더 μ§„ν–‰ν•˜μ§€ μ•Šκ³  μ¦‰μ‹œ aλ₯Ό λ°˜ν™˜ν•˜κ²Œ λœλ‹€. 이λ₯Ό λ³€μˆ˜ 은닉화라고 ν•œλ‹€.

πŸ“š this​

  • μ‹€ν–‰ μ»¨ν…μŠ€νŠΈμ˜ thisBindingμ—λŠ” this둜 μ§€μ •λœ 객체가 μ €μž₯λœλ‹€.
  • μ‹€ν–‰ μ»¨ν…μŠ€νŠΈ ν™œμ„±ν™” λ‹Ήμ‹œμ— thisκ°€ μ§€μ •λ˜μ§€ μ•Šμ€ 경우 thisμ—λŠ” μ „μ—­ 객체가 μ €μž₯λœλ‹€.
  • κ·Έλ°–μ—λŠ” ν•¨μˆ˜λ₯Ό ν˜ΈμΆœν•˜λŠ” 방법에 따라 this에 μ €μž₯λ˜λŠ” λŒ€μƒμ΄ λ‹€λ₯΄λ‹€.
  • 3μž₯ μ°Έκ³ 

πŸ“š 정리​

  • μ‹€ν–‰ μ»¨ν…μŠ€νŠΈλŠ” μ‹€ν–‰ν•  μ½”λ“œμ— μ œκ³΅ν•  ν™˜κ²½ 정보듀을 λͺ¨μ•„놓은 객체이닀.
  • μ‹€ν–‰ μ»¨ν…μŠ€νŠΈλŠ” μ „μ—­ κ³΅κ°„μ—μ„œ μžλ™μœΌλ‘œ μƒμ„±λ˜λŠ” μ „μ—­ μ»¨ν…μŠ€νŠΈμ™€ eval 및 ν•¨μˆ˜ 싀행에 μ˜ν•œ μ»¨ν…μŠ€νŠΈ 등이 μžˆλ‹€.
  • μ‹€ν–‰ μ»¨ν…μŠ€νŠΈ κ°μ²΄λŠ” ν™œμ„±ν™”λ˜λŠ” μ‹œμ μ— VariableEnvironment, LexicalEnvironment, ThisBinding의 μ„Έ 가지 정보λ₯Ό μˆ˜μ§‘ν•œλ‹€.
  • μ‹€ν–‰ μ»¨ν…μŠ€νŠΈλ₯Ό 생성할 λ•ŒλŠ” VariableEnvironment와 LexicalEnvironmentκ°€ λ™μΌν•œ λ‚΄μš©μœΌλ‘œ κ΅¬μ„±ν•˜μ§€λ§Œ LexicalEnvironmentλŠ” ν•¨μˆ˜ μ‹€ν–‰ 도쀑에 λ³€κ²½λ˜λŠ” 사항이 μ¦‰μ‹œ λ°˜μ˜λ˜λŠ” 반면 VariableEnvironmentλŠ” 초기 μƒνƒœλ₯Ό μœ μ§€ν•œλ‹€.
  • VariableEnvironment와 LexicalEnvironmentλŠ” λ§€κ°œλ³€μˆ˜λͺ…, λ³€μˆ˜μ˜ μ‹λ³„μž, μ„ μ–Έν•œ ν•¨μˆ˜μ˜ ν•¨μˆ˜λͺ… 등을 μˆ˜μ§‘ν•˜λŠ” environmentRecord와 λ°”λ‘œ 직전 μ»¨ν…μŠ€νŠΈμ˜ LexicalEnvironment 정보λ₯Ό μ°Έμ‘°ν•˜λŠ” outerEnvironmentReference둜 ꡬ성돼 μžˆλ‹€.
  • ν˜Έμ΄μŠ€νŒ…μ€ μ½”λ“œ 해석을 μ’€ 더 μˆ˜μ›”ν•˜κ²Œ ν•˜κΈ° μœ„ν•΄ environmentRecord의 μˆ˜μ§‘ 과정을 μΆ”μƒν™”ν•œ κ°œλ…μœΌλ‘œ, μ‹€ν–‰ μ»¨ν…μŠ€νŠΈκ°€ κ΄€μ—¬ν•˜λŠ” μ½”λ“œ μ§‘λ‹¨μ˜ μ΅œμƒλ‹¨μœΌλ‘œ 이듀을 λŒμ–΄μ˜¬λ¦°λ‹€λΌκ³  ν•΄μ„ν•˜λŠ” 것이닀. μ΄λ•Œ λ³€μˆ˜ μ„ μ–Έκ³Ό κ°’ 할당이 λ™μ‹œμ— 이뀄진 λ¬Έμž₯은 μ„ μ–ΈλΆ€λ§Œμ„ ν˜Έμ΄μŠ€νŒ…ν•˜κ³ , ν• λ‹Ή 과정은 μ›λž˜ μžλ¦¬μ— λ‚¨μ•„μžˆκ²Œ λ˜λŠ”λ°, μ—¬κΈ°μ„œ ν•¨μˆ˜ μ„ μ–Έλ¬Έκ³Ό ν•¨μˆ˜ ν‘œν˜„μ‹μ˜ 차이가 λ°œμƒν•œλ‹€.
  • μŠ€μ½”ν”„λŠ” λ³€μˆ˜μ˜ μœ νš¨λ²”μœ„λ₯Ό λ§ν•œλ‹€. outerEnvironmentReferenceλŠ” ν•΄λ‹Ή ν•¨μˆ˜κ°€ μ„ μ–Έλœ μœ„μΉ˜μ˜ LexicalEnvironmentλ₯Ό μ°Έμ‘°ν•œλ‹€. μ½”λ“œ μƒμ—μ„œ μ–΄λ–€ λ³€μˆ˜μ— μ ‘κ·Όν•˜λ €κ³  ν•˜λ©΄ ν˜„μž¬ μ»¨ν…μŠ€νŠΈμ˜ LexicalEnvironmentλ₯Ό νƒμƒ‰ν•΄μ„œ 발견되면 κ·Έ 값을 λ°˜ν™˜ν•˜κ³ , λ°œκ²¬λ˜μ§€ λͺ»ν•  경우 λ‹€μ‹œ outerEnvironmentReference에 λ‹΄κΈ΄ LexicalEnvironmentλ₯Ό νƒμƒ‰ν•˜λŠ” 과정을 κ±°μΉœλ‹€. λ§Œμ•½ μ „μ—­ μ»¨ν…μŠ€νŠΈμ˜ LexicalEnvironmentκΉŒμ§€ 탐색해도 ν•΄λ‹Ή λ³€μˆ˜λ₯Ό 찾지 λͺ»ν•˜λ©΄ undefinedλ₯Ό λ°˜ν™˜ν•œλ‹€.
  • thisλŠ” μ‹€ν–‰ μ»¨ν…μŠ€νŠΈλ₯Ό ν™œμ„±ν™”ν•˜λŠ” λ‹Ήμ‹œμ— μ§€μ •λœ thisκ°€ μ €μž₯λ˜λŠ”λ° ν•¨μˆ˜λ₯Ό ν˜ΈμΆœν•˜λŠ” 방법에 따라 κ·Έ 값이 달라진닀. μ§€μ •λ˜μ§€ μ•Šμ€ κ²½μš°μ—λŠ” μ „μ—­ 객체가 μ €μž₯λœλ‹€.