Language/JavaScript

[JS] πŸ“š μžλ°”μŠ€ν¬λ¦½νŠΈ μ‹€ν–‰ μ»¨ν…μŠ€νŠΈ 원리

인파_ 2021. 10. 6. 17:02

μžλ°”μŠ€ν¬λ¦½νŠΈ-μ‹€ν–‰μ»¨ν…μŠ€νŠΈ

μ‹€ν–‰ μ»¨ν…μŠ€νŠΈ

​싀행 μ»¨ν…μŠ€νŠΈ(Execution Context)λŠ” scope, hoisting, this, function, closure λ“±μ˜ λ™μž‘μ›λ¦¬λ₯Ό λ‹΄κ³  μžˆλŠ” μžλ°”μŠ€ν¬λ¦½νŠΈμ˜ 핡심원리이닀.

μ‹€ν–‰ μ»¨ν…μŠ€νŠΈλ₯Ό λ°”λ‘œ μ΄ν•΄ν•˜μ§€ λͺ»ν•˜λ©΄ μ½”λ“œ 독해가 μ–΄λ €μ›Œμ§€λ©° 디버깅도 맀우 κ³€λž€ν•΄ 질 것이닀.

​

μžλ°”μŠ€ν¬λ¦½νŠΈ 엔진은 μ½”λ“œλ₯Ό μ‹€ν–‰ν•˜κΈ° μœ„ν•˜μ—¬ 싀행에 ν•„μš”ν•œ μ—¬λŸ¬κ°€μ§€ 정보λ₯Ό μ•Œκ³  μžˆμ–΄μ•Ό ν•œλ‹€.

싀행에 ν•„μš”ν•œ μ—¬λŸ¬κ°€μ§€ μ •λ³΄λž€ μ•„λž˜μ™€ 같은 것듀이 μžˆλ‹€.

  • λ³€μˆ˜ : μ „μ—­λ³€μˆ˜, μ§€μ—­λ³€μˆ˜, λ§€κ°œλ³€μˆ˜, 객체의 ν”„λ‘œνΌν‹°
  • ν•¨μˆ˜ μ„ μ–Έ
  • λ³€μˆ˜μ˜ μœ νš¨λ²”μœ„(Scope)
  • this

이와 같이 싀행에 ν•„μš”ν•œ 정보λ₯Ό ν˜•μƒν™”ν•˜κ³  κ΅¬λΆ„ν•˜κΈ° μœ„ν•΄ μžλ°”μŠ€ν¬λ¦½νŠΈ 엔진은 μ‹€ν–‰ μ»¨ν…μŠ€νŠΈλ₯Ό 물리적 객체의 ν˜•νƒœλ‘œ κ΄€λ¦¬ν•œλ‹€.

​

μ•„λž˜μ˜ μ½”λ“œλ₯Ό μ‚΄νŽ΄λ³΄μž.

var x = 'xxx';

function foo () {
  var y = 'yyy';

  function bar () {
    var z = 'zzz';
    console.log(x + y + z);
  }
  bar();
}
foo();

μœ„ μ½”λ“œλ₯Ό μ‹€ν–‰ν•˜λ©΄ μ•„λž˜μ™€ 같이 μ‹€ν–‰ μ»¨ν…μŠ€νŠΈ μŠ€νƒ(Stack)이 μƒμ„±ν•˜κ³  μ†Œλ©Έν•œλ‹€.

ν˜„μž¬ μ‹€ν–‰ 쀑인 μ»¨ν…μŠ€νŠΈμ—μ„œ 이 μ»¨ν…μŠ€νŠΈμ™€ κ΄€λ ¨μ—†λŠ” μ½”λ“œ(예λ₯Ό λ“€μ–΄ λ‹€λ₯Έ ν•¨μˆ˜)κ°€ μ‹€ν–‰λ˜λ©΄ μƒˆλ‘œμš΄ μ»¨ν…μŠ€νŠΈκ°€ μƒμ„±λœλ‹€.

이 μ»¨ν…μŠ€νŠΈλŠ” μŠ€νƒμ— μŒ“μ΄κ²Œ 되고 컨트둀(μ œμ–΄κΆŒ)이 μ΄λ™ν•œλ‹€.

μžλ°”μŠ€ν¬λ¦½νŠΈ-μ‹€ν–‰μ»¨ν…μŠ€νŠΈ


μ‹€ν–‰ μ»¨ν…μŠ€νŠΈμ˜ 3가지 객체

​싀행 μ»¨ν…μŠ€νŠΈλŠ” μ‹€ν–‰ κ°€λŠ₯ν•œ μ½”λ“œλ₯Ό ν˜•μƒν™”ν•˜κ³  κ΅¬λΆ„ν•˜λŠ” 좔상적인 κ°œλ…μ΄μ§€λ§Œ

λ¬Όλ¦¬μ μœΌλ‘œλŠ” 객체의 ν˜•νƒœλ₯Ό 가지며 μ•„λž˜μ˜ 3가지 ν”„λ‘œνΌν‹°λ₯Ό μ†Œμœ ν•œλ‹€.

μžλ°”μŠ€ν¬λ¦½νŠΈ-μ‹€ν–‰μ»¨ν…μŠ€νŠΈ


Variable Object (VO / λ³€μˆ˜κ°μ²΄)

μ‹€ν–‰ μ»¨ν…μŠ€νŠΈκ°€ μƒμ„±λ˜λ©΄ μžλ°”μŠ€ν¬λ¦½νŠΈ 엔진은 싀행에 ν•„μš”ν•œ μ—¬λŸ¬ 정보듀을 담을 객체λ₯Ό μƒμ„±ν•œλ‹€.

​

Variable ObjectλŠ” μ•„λž˜μ˜ 정보λ₯Ό λ‹΄λŠ” 객체이닀.

  • λ³€μˆ˜
  • λ§€κ°œλ³€μˆ˜(parameter)와 인수 정보(arguments)
  • ν•¨μˆ˜ μ„ μ–Έ(ν•¨μˆ˜ ν‘œν˜„μ‹μ€ μ œμ™Έ)

​

Variable ObjectλŠ” μ‹€ν–‰ μ»¨ν…μŠ€νŠΈμ˜ ν”„λ‘œνΌν‹°μ΄κΈ° λ•Œλ¬Έμ— 값을 κ°–λŠ”λ° 이 값은 λ‹€λ₯Έ 객체λ₯Ό 가리킨닀.

그런데 μ „μ—­ μ½”λ“œ μ‹€ν–‰μ‹œ μƒμ„±λ˜λŠ” μ „μ—­ μ»¨ν…μŠ€νŠΈμ˜ κ²½μš°μ™€ ν•¨μˆ˜λ₯Ό μ‹€ν–‰ν•  λ•Œ μƒμ„±λ˜λŠ” ν•¨μˆ˜ μ»¨ν…μŠ€νŠΈμ˜ 경우, κ°€λ¦¬ν‚€λŠ” 객체가 λ‹€λ₯΄λ‹€.

μ΄λŠ” μ „μ—­ μ½”λ“œμ™€ ν•¨μˆ˜μ˜ λ‚΄μš©μ΄ λ‹€λ₯΄κΈ° λ•Œλ¬Έμ΄λ‹€. 예λ₯Ό λ“€μ–΄ μ „μ—­ μ½”λ“œμ—λŠ” λ§€κ°œλ³€μˆ˜κ°€ μ—†μ§€λ§Œ ν•¨μˆ˜μ—λŠ” λ§€κ°œλ³€μˆ˜κ°€ μžˆλ‹€.

​

μ „μ—­ μ»¨ν…μŠ€νŠΈμ˜ 경우

Variable ObjectλŠ” μœ μΌν•˜λ©° μ΅œμƒμœ„μ— μœ„μΉ˜ν•˜κ³  λͺ¨λ“  μ „μ—­ λ³€μˆ˜, μ „μ—­ ν•¨μˆ˜ 등을 ν¬ν•¨ν•˜λŠ” μ „μ—­ 객체(Global Object / GO)λ₯Ό 가리킨닀.

μ „μ—­ κ°μ²΄λŠ” 전역에 μ„ μ–Έλœ μ „μ—­ λ³€μˆ˜μ™€ μ „μ—­ ν•¨μˆ˜λ₯Ό ν”„λ‘œνΌν‹°λ‘œ μ†Œμœ ν•œλ‹€.

μžλ°”μŠ€ν¬λ¦½νŠΈ-μ‹€ν–‰μ»¨ν…μŠ€νŠΈ

​

ν•¨μˆ˜ μ»¨ν…μŠ€νŠΈμ˜ 경우

Variable ObjectλŠ” Activation Object(AO / ν™œμ„± 객체)λ₯Ό 가리킀며 λ§€κ°œλ³€μˆ˜μ™€ μΈμˆ˜λ“€μ˜ 정보λ₯Ό λ°°μ—΄μ˜ ν˜•νƒœλ‘œ λ‹΄κ³  μžˆλŠ” 객체인 argument객체가 μΆ”κ°€λœλ‹€.

μžλ°”μŠ€ν¬λ¦½νŠΈ-μ‹€ν–‰μ»¨ν…μŠ€νŠΈ


Scope Chain (SC)

μŠ€μ½”ν”„ 체인(Scope Chain)은 ​해당 μ „μ—­ λ˜λŠ” ν•¨μˆ˜κ°€ μ°Έμ‘°ν•  수 μžˆλŠ” λ³€μˆ˜, ν•¨μˆ˜ μ„ μ–Έ λ“±μ˜ 정보λ₯Ό λ‹΄κ³  μžˆλŠ” μ „μ—­ 객체(GO) λ˜λŠ” ν™œμ„± 객체(AO)의 리슀트λ₯Ό 가리킨닀.

​

ν˜„μž¬ μ‹€ν–‰ μ»¨ν…μŠ€νŠΈμ˜ ν™œμ„± 객체(AO)λ₯Ό μ„ λ‘λ‘œ ν•˜μ—¬ 순차적으둜 μƒμœ„ μ»¨ν…μŠ€νŠΈμ˜ ν™œμ„± 객체(AO)λ₯Ό 가리킀며 λ§ˆμ§€λ§‰ λ¦¬μŠ€νŠΈλŠ” μ „μ—­ 객체(GO)λ₯Ό 가리킨닀.

μžλ°”μŠ€ν¬λ¦½νŠΈ-μ‹€ν–‰μ»¨ν…μŠ€νŠΈ

μŠ€μ½”ν”„ 체인은 μ‹λ³„μž μ€‘μ—μ„œ 객체(μ „μ—­ 객체 μ œμ™Έ)의 ν”„λ‘œνΌν‹°κ°€ μ•„λ‹Œ μ‹λ³„μž, 즉 λ³€μˆ˜λ₯Ό κ²€μƒ‰ν•˜λŠ” λ©”μ»€λ‹ˆμ¦˜μ΄λ‹€.​

μ‹λ³„μž μ€‘μ—μ„œ λ³€μˆ˜κ°€ μ•„λ‹Œ κ°μ²΄μ˜ ν”„λ‘œνΌν‹°(λ¬Όλ‘  λ©”μ†Œλ“œλ„ ν¬ν•¨λœλ‹€)λ₯Ό κ²€μƒ‰ν•˜λŠ” λ©”μ»€λ‹ˆμ¦˜μ€ ν”„λ‘œν† νƒ€μž… 체인(Prototype Chain)이닀.

* μ‹λ³„μž : λ³€μˆ˜λͺ…,ν•¨μˆ˜λͺ…,객체λͺ… λ“± 이름을 뢙일떄 μ‚¬μš©ν•˜λŠ” 단어

​

​엔진은 μŠ€μ½”ν”„ 체인을 톡해 λ ‰μ‹œμ»¬ μŠ€μ½”ν”„λ₯Ό νŒŒμ•…ν•œλ‹€.

ν•¨μˆ˜κ°€ 쀑첩 μƒνƒœμΌ λ•Œ ν•˜μœ„ν•¨μˆ˜ λ‚΄μ—μ„œ μƒμœ„ν•¨μˆ˜μ˜ μŠ€μ½”ν”„μ™€ μ „μ—­ μŠ€μ½”ν”„κΉŒμ§€ μ°Έμ‘°ν•  수 μžˆλŠ”λ° μ΄κ²ƒλŠ” μŠ€μ½”ν”„ 체인을 검색을 톡해 κ°€λŠ₯ν•˜λ‹€.

​

ν•¨μˆ˜κ°€ μ€‘μ²©λ˜μ–΄ 있으면 쀑첩될 λ•Œλ§ˆλ‹€ λΆ€λͺ¨ ν•¨μˆ˜μ˜ Scopeκ°€ μžμ‹ ν•¨μˆ˜μ˜ μŠ€μ½”ν”„ 체인에 ν¬ν•¨λœλ‹€.

ν•¨μˆ˜ 싀행쀑에 λ³€μˆ˜λ₯Ό λ§Œλ‚˜λ©΄ κ·Έ λ³€μˆ˜λ₯Ό μš°μ„  ν˜„μž¬ Scope, 즉 Activation Objectμ—μ„œ 검색해보고, λ§Œμ•½ 검색에 μ‹€νŒ¨ν•˜λ©΄ μŠ€μ½”ν”„ 체인에 담겨진 μˆœμ„œλŒ€λ‘œ κ·Έ 검색을 μ΄μ–΄κ°€κ²Œ λ˜λŠ” 것이닀.

이것이 μŠ€μ½”ν”„ 체인이라고 λΆˆλ¦¬λŠ” μ΄μœ μ΄λ‹€.

​

예λ₯Ό λ“€μ–΄ ν•¨μˆ˜ λ‚΄μ˜ μ½”λ“œμ—μ„œ λ³€μˆ˜λ₯Ό μ°Έμ‘°ν•˜λ©΄ 엔진은 μŠ€μ½”ν”„ 체인의 첫번째 λ¦¬μŠ€νŠΈκ°€ κ°€λ¦¬ν‚€λŠ” AO에 μ ‘κ·Όν•˜μ—¬ λ³€μˆ˜λ₯Ό κ²€μƒ‰ν•œλ‹€. 만일 검색에 μ‹€νŒ¨ν•˜λ©΄ λ‹€μŒ λ¦¬μŠ€νŠΈκ°€ κ°€λ¦¬ν‚€λŠ” Activation Object(λ˜λŠ” μ „μ—­ 객체)λ₯Ό κ²€μƒ‰ν•œλ‹€. 이와 같이 순차적으둜 μŠ€μ½”ν”„ μ²΄μΈμ—μ„œ λ³€μˆ˜λ₯Ό κ²€μƒ‰ν•˜λŠ”λ° κ²°κ΅­ 검색에 μ‹€νŒ¨ν•˜λ©΄ μ •μ˜λ˜μ§€ μ•Šμ€ λ³€μˆ˜μ— μ ‘κ·Όν•˜λŠ” κ²ƒμœΌλ‘œ νŒλ‹¨ν•˜μ—¬ Reference μ—λŸ¬λ₯Ό λ°œμƒμ‹œν‚¨λ‹€.

​

μŠ€μ½”ν”„ 체인은 ν•¨μˆ˜μ˜ ν”„λ‘œνΌν‹°μΈ [[Scope]]둜 μ°Έμ‘°ν•  수 μžˆλ‹€.

μžλ°”μŠ€ν¬λ¦½νŠΈ-μ‹€ν–‰μ»¨ν…μŠ€νŠΈ


this value

this ν”„λ‘œνΌν‹°μ—λŠ” this 값이 ν• λ‹Ήλœλ‹€.

this ν• λ‹Ήλ˜λŠ” 값은 ν•¨μˆ˜ 호좜 νŒ¨ν„΄μ— μ˜ν•΄ κ²°μ •λœλ‹€.

 

[JS] πŸ“š this 총정리

this μ •μ˜ let group = { title: "1λͺ¨λ‘ ", students: ["보라", "ν˜Έμ§„", "지민"], title2 : this.title, title3() { console.log(this.title) } }; console.log(group.title2); //undefined group.title3(); // 1..

inpa.tistory.com


μ‹€ν–‰ μ»¨ν…μŠ€νŠΈμ˜ 생성 κ³Όμ •

β€‹μ•žμ—μ„œ μ‚΄νŽ΄λ³Έ μ•„λž˜μ˜ μ½”λ“œλ₯Ό 가지고 μ‹€μ œλ‘œ μ–΄λ–»κ²Œ μ‹€ν–‰ μ»¨ν…μŠ€νŠΈκ°€ μƒμ„±λ˜λŠ”μ§€ μ•Œμ•„λ³΄μž.

var x = 'xxx';

function foo () {
  var y = 'yyy';

  function bar () {
    var z = 'zzz';
    console.log(x + y + z);
  }
  bar();
}

foo();

 

1. μ „μ—­ μ½”λ“œμ—μ˜ μ§„μž…

컨트둀이 μ‹€ν–‰ μ»¨ν…μŠ€νŠΈμ— μ§„μž…ν•˜κΈ° 이전에 μœ μΌν•œ μ „μ—­ 객체(Global Object)κ°€ μƒμ„±λœλ‹€.

μ „μ—­ κ°μ²΄λŠ” 단일 μ‚¬λ³ΈμœΌλ‘œ μ‘΄μž¬ν•˜λ©° 이 객체의 ν”„λ‘œνΌν‹°λŠ” μ½”λ“œμ˜ μ–΄λ– ν•œ κ³³μ—μ„œλ„ μ ‘κ·Όν•  수 μžˆλ‹€.

초기 μƒνƒœμ˜ μ „μ—­ κ°μ²΄μ—λŠ” 빌트인 객체(Math, String, Array λ“±)와 BOM, DOM이 μ„€μ •λ˜μ–΄ μžˆλ‹€.

μžλ°”μŠ€ν¬λ¦½νŠΈ-μ‹€ν–‰μ»¨ν…μŠ€νŠΈ

μ „μ—­ 객체가 μƒμ„±λœ 이후, μ „μ—­ μ½”λ“œλ‘œ 컨트둀이 μ§„μž…ν•˜λ©΄ μ „μ—­ μ‹€ν–‰ μ»¨ν…μŠ€νŠΈκ°€ μƒμ„±λ˜κ³  μ‹€ν–‰ μ»¨ν…μŠ€νŠΈ μŠ€νƒμ— μŒ“μΈλ‹€.

μžλ°”μŠ€ν¬λ¦½νŠΈ-μ‹€ν–‰μ»¨ν…μŠ€νŠΈ

그리고 이후 이 μ‹€ν–‰ μ»¨ν…μŠ€νŠΈλ₯Ό λ°”νƒ•μœΌλ‘œ μ΄ν•˜μ˜ μ²˜λ¦¬κ°€ μ‹€ν–‰λœλ‹€.

​

1) μŠ€μ½”ν”„ 체인의 생성과 μ΄ˆκΈ°ν™”

μ‹€ν–‰ μ»¨ν…μŠ€νŠΈκ°€ μƒμ„±λœ 이후 κ°€μž₯ λ¨Όμ € μŠ€μ½”ν”„ 체인의 생성과 μ΄ˆκΈ°ν™”κ°€ μ‹€ν–‰λœλ‹€.

μ΄λ•Œ μŠ€μ½”ν”„ 체인은 μ „μ—­ 객체의 레퍼런슀λ₯Ό ν¬ν•¨ν•˜λŠ” λ¦¬μŠ€νŠΈκ°€ λœλ‹€.

μžλ°”μŠ€ν¬λ¦½νŠΈ-μ‹€ν–‰μ»¨ν…μŠ€νŠΈ

​

​

2) Variable Instantiation(λ³€μˆ˜ 객체화) μ‹€ν–‰

μŠ€μ½”ν”„ 체인의 생성과 μ΄ˆκΈ°ν™”κ°€ μ’…λ£Œν•˜λ©΄ λ³€μˆ˜ 객체화(Variable Instantiation)κ°€ μ‹€ν–‰λœλ‹€.

λ³€μˆ˜, λ§€κ°œλ³€μˆ˜μ™€ 인수 정보(arguments), ν•¨μˆ˜ 선언을 Variable Object에 μΆ”κ°€ν•˜μ—¬ 객체화 ν•œλ‹€.

μ „μ—­ μ½”λ“œμ˜ 경우, Variable ObjectλŠ” Global Objectλ₯Ό 가리킨닀.

μžλ°”μŠ€ν¬λ¦½νŠΈ-μ‹€ν–‰μ»¨ν…μŠ€νŠΈ

​

Variable Instantiation(λ³€μˆ˜ 객체화)λŠ” μ•„λž˜μ˜ μˆœμ„œλ‘œ Variable Object에 ν”„λ‘œνΌν‹°μ™€ 값을 setν•œλ‹€. (λ°˜λ“œμ‹œ 1→2→3 μˆœμ„œλ‘œ μ‹€ν–‰λœλ‹€.)

1. (Function Code인 경우) λ§€κ°œλ³€μˆ˜(parameter)κ°€ Variable Object의 ν”„λ‘œνΌν‹°λ‘œ, 인수(argument)κ°€ κ°’μœΌλ‘œ μ„€μ •λœλ‹€.
​
2. λŒ€μƒ μ½”λ“œ λ‚΄μ˜ ν•¨μˆ˜ μ„ μ–Έ(ν•¨μˆ˜ ν‘œν˜„μ‹ μ œμ™Έ)을 λŒ€μƒμœΌλ‘œ ν•¨μˆ˜λͺ…이 Variable Object의 ν”„λ‘œνΌν‹°λ‘œ, μƒμ„±λœ ν•¨μˆ˜ 객체가 κ°’μœΌλ‘œ μ„€μ •λœλ‹€.(ν•¨μˆ˜ ν˜Έμ΄μŠ€νŒ…)
​
3. λŒ€μƒ μ½”λ“œ λ‚΄μ˜ λ³€μˆ˜ 선언을 λŒ€μƒμœΌλ‘œ λ³€μˆ˜λͺ…이 Variable Object의 ν”„λ‘œνΌν‹°λ‘œ, undefinedκ°€ κ°’μœΌλ‘œ μ„€μ •λœλ‹€.(λ³€μˆ˜ ν˜Έμ΄μŠ€νŒ…)

β€‹μœ„ 예제 μ½”λ“œλ₯Ό 보면 μ „μ—­ μ½”λ“œμ— λ³€μˆ˜ x와 ν•¨μˆ˜ foo(λ§€κ°œλ³€μˆ˜ μ—†μŒ)κ°€ μ„ μ–Έλ˜μ—ˆλ‹€.

Variable Instantiation의 μ‹€ν–‰ μˆœμ„œ 상, μš°μ„  2. ν•¨μˆ˜ foo의 선언이 처리되고(ν•¨μˆ˜ μ½”λ“œκ°€ μ•„λ‹Œ μ „μ—­ μ½”λ“œμ΄κΈ° λ•Œλ¬Έμ— 1. λ§€κ°œλ³€μˆ˜ μ²˜λ¦¬λŠ” μ‹€ν–‰λ˜μ§€ μ•ŠλŠ”λ‹€.) κ·Έ ν›„ 3. λ³€μˆ˜ x의 선언이 μ²˜λ¦¬λœλ‹€.

​

​

3) ν•¨μˆ˜ foo의 μ„ μ–Έ 처리

ν•¨μˆ˜ 선언은 Variable Instantiation μ‹€ν–‰ μˆœμ„œ 2.와 같이 μ„ μ–Έλœ ν•¨μˆ˜λͺ… fooκ°€ Variable Object(μ „μ—­ μ½”λ“œμΈ 경우 Global Object)의 ν”„λ‘œνΌν‹°λ‘œ, μƒμ„±λœ ν•¨μˆ˜ 객체가 κ°’μœΌλ‘œ μ„€μ •λœλ‹€.

μžλ°”μŠ€ν¬λ¦½νŠΈ-μ‹€ν–‰μ»¨ν…μŠ€νŠΈ

​

μƒμ„±λœ ν•¨μˆ˜ κ°μ²΄λŠ” [[Scopes]] ν”„λ‘œνΌν‹°λ₯Ό κ°€μ§€κ²Œ λœλ‹€.

[[Scopes]] ν”„λ‘œνΌν‹°λŠ” ν•¨μˆ˜ 객체만이 μ†Œμœ ν•˜λŠ” λ‚΄λΆ€ ν”„λ‘œνΌν‹°(Internal Property)λ‘œμ„œ ν•¨μˆ˜ 객체가 μ‹€ν–‰λ˜λŠ” ν™˜κ²½μ„ 가리킨닀.

​

λ”°λΌμ„œ ν˜„μž¬ μ‹€ν–‰ μ»¨ν…μŠ€νŠΈμ˜ μŠ€μ½”ν”„ 체인이 μ°Έμ‘°ν•˜κ³  μžˆλŠ” 객체λ₯Ό κ°’μœΌλ‘œ μ„€μ •ν•œλ‹€.

λ‚΄λΆ€ ν•¨μˆ˜μ˜ [[Scopes]] ν”„λ‘œνΌν‹°λŠ” μžμ‹ μ˜ μ‹€ν–‰ ν™˜κ²½(Lexical Enviroment)κ³Ό μžμ‹ μ„ ν¬ν•¨ν•˜λŠ” μ™ΈλΆ€ ν•¨μˆ˜μ˜ μ‹€ν–‰ ν™˜κ²½κ³Ό μ „μ—­ 객체λ₯Ό κ°€λ¦¬ν‚€λŠ”λ°,

μ΄λ•Œ μžμ‹ μ„ ν¬ν•¨ν•˜λŠ” μ™ΈλΆ€ ν•¨μˆ˜μ˜ μ‹€ν–‰ μ»¨ν…μŠ€νŠΈκ°€ μ†Œλ©Έν•˜μ—¬λ„ [[Scopes]] ν”„λ‘œνΌν‹°κ°€ κ°€λ¦¬ν‚€λŠ” μ™ΈλΆ€ ν•¨μˆ˜μ˜ μ‹€ν–‰ ν™˜κ²½(Activation object)은 μ†Œλ©Έν•˜μ§€ μ•Šκ³  μ°Έμ‘°ν•  수 μžˆλ‹€.

​

이것이 ν΄λ‘œμ €μ΄λ‹€.

 

μžλ°”μŠ€ν¬λ¦½νŠΈ-μ‹€ν–‰μ»¨ν…μŠ€νŠΈ

​

μ§€κΈˆκΉŒμ§€ μ‚΄νŽ΄λ³Έ μ‹€ν–‰ μ»¨ν…μŠ€νŠΈλŠ” 아직 μ½”λ“œκ°€ μ‹€ν–‰λ˜κΈ° 이전이닀.

ν•˜μ§€λ§Œ μŠ€μ½”ν”„ 체인이 κ°€λ¦¬ν‚€λŠ” λ³€μˆ˜ 객체(VO)에 이미 ν•¨μˆ˜κ°€ λ“±λ‘λ˜μ–΄ μžˆμœΌλ―€λ‘œ 이후 μ½”λ“œλ₯Ό μ‹€ν–‰ν•  λ•Œ ν•¨μˆ˜μ„ μ–Έμ‹ 이전에 ν•¨μˆ˜λ₯Ό ν˜ΈμΆœν•  수 있게 λ˜μ—ˆλ‹€.

μ΄λ•Œ μ•Œ 수 μžˆλŠ” 것은 ν•¨μˆ˜μ„ μ–Έμ‹μ˜ 경우, λ³€μˆ˜ 객체(VO)에 ν•¨μˆ˜ν‘œν˜„μ‹κ³Ό λ™μΌν•˜κ²Œ ν•¨μˆ˜λͺ…을 ν”„λ‘œνΌν‹°λ‘œ ν•¨μˆ˜ 객체λ₯Ό ν• λ‹Ήν•œλ‹€λŠ” 것이닀.

단, ν•¨μˆ˜μ„ μ–Έμ‹μ€ λ³€μˆ˜ 객체(VO)에 ν•¨μˆ˜λͺ…을 ν”„λ‘œνΌν‹°λ‘œ μΆ”κ°€ν•˜κ³  μ¦‰μ‹œ ν•¨μˆ˜ 객체λ₯Ό μ¦‰μ‹œ ν• λ‹Ήν•˜μ§€λ§Œ

ν•¨μˆ˜ ν‘œν˜„μ‹μ€ 일반 λ³€μˆ˜μ˜ 방식(λ‚˜μ€‘μ— ν•¨μˆ˜ 객체 ν• λ‹Ή)을 λ”°λ₯Έλ‹€.

​

λ”°λΌμ„œ ν•¨μˆ˜μ„ μ–Έμ‹μ˜ 경우, μ„ μ–Έλ¬Έ 이전에 ν•¨μˆ˜λ₯Ό ν˜ΈμΆœν•  수 μžˆλ‹€.

μ΄λŸ¬ν•œ ν˜„μƒμ„ ν•¨μˆ˜ ν˜Έμ΄μŠ€νŒ…(Function Hoisting)이라 ν•œλ‹€.

console.log(a()); // 11
console.log(b()); // Uncaught TypeError: b is not a function
                  // ν˜„μž¬ VOμ—λŠ” λ³€μˆ˜λ‘œμ„œ bκ°€ μ €μž₯λ˜μ–΄μžˆλ‹€. κ·ΈλŸ¬λ‹ˆ b()ν•˜λ©΄ bλŠ” ν•¨μˆ˜κ°€ μ•„λ‹ˆλ‹€λΌκ³  λœ¬λ‹€. 
function a() {
    return '11';
}
 
var b = function() {
    return '22';
}

​

​

4) λ³€μˆ˜ x의 μ„ μ–Έ 처리

λ³€μˆ˜ 선언은 Variable Instantiation μ‹€ν–‰ μˆœμ„œ 3.κ³Ό 같이 μ„ μ–Έλœ λ³€μˆ˜λͺ…( x )이 Variable Object의 ν”„λ‘œνΌν‹°λ‘œ, undefinedκ°€ κ°’μœΌλ‘œ μ„€μ •λœλ‹€.

​

이것을 쒀더 μ„ΈλΆ„ν™” 해보면 μ•„λž˜μ™€ κ°™λ‹€.

μ„ μ–Έ 단계(Declaration phase)
λ³€μˆ˜ 객체(Variable Object)에 λ³€μˆ˜λ₯Ό λ“±λ‘ν•œλ‹€. 이 λ³€μˆ˜ κ°μ²΄λŠ” μŠ€μ½”ν”„κ°€ μ°Έμ‘°ν•  수 μžˆλŠ” λŒ€μƒμ΄ λœλ‹€.
​
μ΄ˆκΈ°ν™” 단계(Initialization phase)
λ³€μˆ˜ 객체(Variable Object)에 λ“±λ‘λœ λ³€μˆ˜λ₯Ό λ©”λͺ¨λ¦¬μ— ν• λ‹Ήν•œλ‹€. 이 λ‹¨κ³„μ—μ„œ λ³€μˆ˜λŠ” undefined둜 μ΄ˆκΈ°ν™”λœλ‹€.
​
ν• λ‹Ή 단계(Assignment phase)
undefined둜 μ΄ˆκΈ°ν™”λœ λ³€μˆ˜μ— μ‹€μ œκ°’μ„ ν• λ‹Ήν•œλ‹€.

 

var ν‚€μ›Œλ“œλ‘œ μ„ μ–Έλœ λ³€μˆ˜λŠ” μ„ μ–Έ 단계와 μ΄ˆκΈ°ν™” 단계가 ν•œλ²ˆμ— 이루어진닀.

​

λ‹€μ‹œ 말해 μŠ€μ½”ν”„ 체인이 κ°€λ¦¬ν‚€λŠ” λ³€μˆ˜ 객체에 λ³€μˆ˜κ°€ λ“±λ‘λ˜κ³  λ³€μˆ˜λŠ” undefined둜 μ΄ˆκΈ°ν™”λœλ‹€.

λ”°λΌμ„œ λ³€μˆ˜ μ„ μ–Έλ¬Έ 이전에 λ³€μˆ˜μ— μ ‘κ·Όν•˜μ—¬λ„ Variable Object에 λ³€μˆ˜κ°€ μ‘΄μž¬ν•˜κΈ° λ•Œλ¬Έμ— μ—λŸ¬κ°€ λ°œμƒν•˜μ§€ μ•ŠλŠ”λ‹€. λ‹€λ§Œ undefinedλ₯Ό λ°˜ν™˜ν•œλ‹€.

​

μ΄λŸ¬ν•œ ν˜„μƒμ„ λ³€μˆ˜ ν˜Έμ΄μŠ€νŒ…(Variable Hoisting)μ΄λΌν•œλ‹€.

console.log(a);  // undefined
var a = 10;
console.log(a);  // 10
console.log(a);  // ReferenceError: a is not defined
let a = 10;

μžλ°”μŠ€ν¬λ¦½νŠΈ-μ‹€ν–‰μ»¨ν…μŠ€νŠΈ

아직 λ³€μˆ˜ xλŠ” ‘xxx’둜 μ΄ˆκΈ°ν™”λ˜μ§€ μ•Šμ•˜λ‹€.

이후 λ³€μˆ˜ 할당문에 λ„λ‹¬ν•˜λ©΄ λΉ„λ‘œμ†Œ κ°’μ˜ 할당이 이루어진닀.

​

​

5) this value κ²°μ •

λ³€μˆ˜ μ„ μ–Έ μ²˜λ¦¬κ°€ λλ‚˜λ©΄ λ‹€μŒμ€ this valueκ°€ κ²°μ •λœλ‹€.

this valueκ°€ κ²°μ •λ˜κΈ° 이전에 thisλŠ” μ „μ—­ 객체λ₯Ό 가리킀고 μžˆλ‹€κ°€ ν•¨μˆ˜ 호좜 νŒ¨ν„΄μ— μ˜ν•΄ this에 ν• λ‹Ήλ˜λŠ” 값이 κ²°μ •λœλ‹€.

μ „μ—­ μ½”λ“œμ˜ 경우, thisλŠ” μ „μ—­ 객체λ₯Ό 가리킨닀.

μžλ°”μŠ€ν¬λ¦½νŠΈ-μ‹€ν–‰μ»¨ν…μŠ€νŠΈ

(μ „μ—­ μ»¨ν…μŠ€νŠΈ(μ „μ—­ μ½”λ“œ)의 경우, Variable Object, μŠ€μ½”ν”„ 체인, this 값은 μ–Έμ œλ‚˜ μ „μ—­ 객체이닀.)


μ „μ—­ μ½”λ“œμ˜ μ‹€ν–‰

β€‹μ§€κΈˆκΉŒμ§€λŠ” μ½”λ“œ μ‹€ν–‰ ν™˜κ²½μ„ κ°–μΆ”κΈ° μœ„ν•œ 사전 μ€€λΉ„μ˜€λ‹€. μ½”λ“œμ˜ 싀행은 μ§€κΈˆλΆ€ν„° μ‹œμž‘λœλ‹€.

var x = 'xxx';

function foo () {
  var y = 'yyy';

  function bar () {
    var z = 'zzz';
    console.log(x + y + z);
  }
  bar();
}

foo();

μœ„ 예제λ₯Ό 보면 μ „μ—­ λ³€μˆ˜ x에 λ¬Έμžμ—΄ ‘xxx’ ν• λ‹Ήκ³Ό ν•¨μˆ˜ foo의 호좜이 μ‹€ν–‰λœλ‹€.

​

​

1) λ³€μˆ˜ κ°’μ˜ ν• λ‹Ή

μ „μ—­ λ³€μˆ˜ x에 λ¬Έμžμ—΄ ‘xxx’λ₯Ό ν• λ‹Ήν•  λ•Œ, ν˜„μž¬ μ‹€ν–‰ μ»¨ν…μŠ€νŠΈμ˜ μŠ€μ½”ν”„ 체인이 μ°Έμ‘°ν•˜κ³  μžˆλŠ” Variable Objectλ₯Ό 선두(0)λΆ€ν„° κ²€μƒ‰ν•˜μ—¬ λ³€μˆ˜λͺ…에 ν•΄λ‹Ήν•˜λŠ” ν”„λ‘œνΌν‹°κ°€ 발견되면 κ°’(‘xxx’)을 ν• λ‹Ήν•œλ‹€.

μžλ°”μŠ€ν¬λ¦½νŠΈ-μ‹€ν–‰μ»¨ν…μŠ€νŠΈ

​

​

2) ν•¨μˆ˜ foo의 μ‹€ν–‰

μ „μ—­ μ½”λ“œμ˜ ν•¨μˆ˜ fooκ°€ μ‹€ν–‰λ˜κΈ° μ‹œμž‘ν•˜λ©΄ μƒˆλ‘œμš΄ ν•¨μˆ˜ μ‹€ν–‰ μ»¨ν…μŠ€νŠΈκ°€ μƒμ„±λœλ‹€.

ν•¨μˆ˜ foo의 μ‹€ν–‰ μ»¨ν…μŠ€νŠΈλ‘œ 컨트둀이 μ΄λ™ν•˜λ©΄ μ „μ—­ μ½”λ“œμ˜ κ²½μš°μ™€ λ§ˆμ°¬κ°€μ§€λ‘œ

  1. μŠ€μ½”ν”„ 체인의 생성과 μ΄ˆκΈ°ν™”,
  2. Variable Instantiation μ‹€ν–‰,
  3. this value κ²°μ •

​이 순차적으둜 μ‹€ν–‰λœλ‹€.

μžλ°”μŠ€ν¬λ¦½νŠΈ-μ‹€ν–‰μ»¨ν…μŠ€νŠΈ

​

​

3) μŠ€μ½”ν”„ 체인의 생성과 μ΄ˆκΈ°ν™”

ν•¨μˆ˜ μ½”λ“œμ˜ μŠ€μ½”ν”„ 체인의 생성과 μ΄ˆκΈ°ν™”λŠ” μš°μ„  Activation Object에 λŒ€ν•œ 레퍼런슀λ₯Ό μŠ€μ½”ν”„ 체인의 선두에 μ„€μ •ν•˜λŠ” κ²ƒμœΌλ‘œ μ‹œμž‘λœλ‹€.

Activation ObjectλŠ” μš°μ„  arguments ν”„λ‘œνΌν‹°μ˜ μ΄ˆκΈ°ν™”λ₯Ό μ‹€ν–‰ν•˜κ³  κ·Έ ν›„, Variable Instantiationκ°€ μ‹€ν–‰λœλ‹€.

Activation ObjectλŠ” μŠ€νŽ™ μƒμ˜ κ°œλ…μœΌλ‘œ, ν”„λ‘œκ·Έλž¨μ΄ Activation Object에 직접 μ ‘κ·Όν•  수 μ—†λ‹€. (Activation Object의 ν”„λ‘œνΌν‹°λ‘œμ˜ 접근은 κ°€λŠ₯ν•˜λ‹€)

μžλ°”μŠ€ν¬λ¦½νŠΈ-μ‹€ν–‰μ»¨ν…μŠ€νŠΈ

​

κ·Έ ν›„, Caller(μ „μ—­ μ»¨ν…μŠ€νŠΈ)의 Scope Chain이 μ°Έμ‘°ν•˜κ³  μžˆλŠ” 객체가 μŠ€μ½”ν”„ 체인에 pushλœλ‹€.

λ”°λΌμ„œ, 이 경우 ν•¨μˆ˜ fooλ₯Ό μ‹€ν–‰ν•œ 직후 μ‹€ν–‰ μ»¨ν…μŠ€νŠΈμ˜ μŠ€μ½”ν”„ 체인은 Activation Object(ν•¨μˆ˜ foo의 μ‹€ν–‰μœΌλ‘œ λ§Œλ“€μ–΄μ§„ AO-1)κ³Ό μ „μ—­ 객체λ₯Ό 순차적으둜 μ°Έμ‘°ν•˜κ²Œ λœλ‹€.

μžλ°”μŠ€ν¬λ¦½νŠΈ-μ‹€ν–‰μ»¨ν…μŠ€νŠΈ

​

​

4) Variable Instantiation λ³€μˆ˜ 객체화 μ‹€ν–‰

Function Code의 경우, μŠ€μ½”ν”„ 체인의 생성과 μ΄ˆκΈ°ν™”μ—μ„œ μƒμ„±λœ Activation Objectλ₯Ό Variable Objectλ‘œμ„œ Variable Instantiationκ°€ μ‹€ν–‰λœλ‹€.

이것을 μ œμ™Έν•˜λ©΄ μ „μ—­ μ½”λ“œμ˜ κ²½μš°μ™€ 같은 μ²˜λ¦¬κ°€ μ‹€ν–‰λœλ‹€.

즉, ν•¨μˆ˜ 객체λ₯Ό Variable Object(AO-1)에 λ°”μΈλ”©ν•œλ‹€. (ν”„λ‘œνΌν‹°λŠ” bar, 값은 μƒˆλ‘œ μƒμ„±λœ Function Object. bar function object의 [[Scope]] ν”„λ‘œνΌν‹° 값은 AO-1κ³Ό Global Objectλ₯Ό μ°Έμ‘°ν•˜λŠ” λ¦¬μŠ€νŠΈοΌ‰

μžλ°”μŠ€ν¬λ¦½νŠΈ-μ‹€ν–‰μ»¨ν…μŠ€νŠΈ

​

yλ₯Ό Variable Object(AO-1)에 μ„€μ •ν•œλ‹€ μ΄λ•Œ ν”„λ‘œνΌν‹°λŠ” y, 값은 undefined이닀.

μžλ°”μŠ€ν¬λ¦½νŠΈ-μ‹€ν–‰μ»¨ν…μŠ€νŠΈ

​

​

5) this value κ²°μ •

λ³€μˆ˜ μ„ μ–Έ μ²˜λ¦¬κ°€ λλ‚˜λ©΄ λ‹€μŒμ€ this valueκ°€ κ²°μ •λœλ‹€. this에 ν• λ‹Ήλ˜λŠ” 값은 ν•¨μˆ˜ 호좜 νŒ¨ν„΄μ— μ˜ν•΄ κ²°μ •λœλ‹€.

λ‚΄λΆ€ ν•¨μˆ˜μ˜ 경우, this의 valueλŠ” μ „μ—­ 객체이닀.

μžλ°”μŠ€ν¬λ¦½νŠΈ-μ‹€ν–‰μ»¨ν…μŠ€νŠΈ


foo ν•¨μˆ˜ μ½”λ“œμ˜ μ‹€ν–‰

이제 ν•¨μˆ˜ foo의 μ½”λ“œ 블둝 λ‚΄ ꡬ문이 μ‹€ν–‰λœλ‹€. μœ„ 예제λ₯Ό 보면 λ³€μˆ˜ y에 λ¬Έμžμ—΄ ‘yyy’의 ν• λ‹Ήκ³Ό ν•¨μˆ˜ barκ°€ μ‹€ν–‰λœλ‹€.

​

​

1) λ³€μˆ˜ κ°’μ˜ ν• λ‹Ή

지역 λ³€μˆ˜ y에 λ¬Έμžμ—΄ ‘yyy’λ₯Ό ν• λ‹Ήν•  λ•Œ, ν˜„μž¬ μ‹€ν–‰ μ»¨ν…μŠ€νŠΈμ˜ μŠ€μ½”ν”„ 체인이 μ°Έμ‘°ν•˜κ³  μžˆλŠ” Variable Objectλ₯Ό 선두(0)λΆ€ν„° κ²€μƒ‰ν•˜μ—¬ λ³€μˆ˜λͺ…에 ν•΄λ‹Ήν•˜λŠ” ν”„λ‘œνΌν‹°κ°€ 발견되면 κ°’ ‘yyy’λ₯Ό ν• λ‹Ήν•œλ‹€.

μžλ°”μŠ€ν¬λ¦½νŠΈ-μ‹€ν–‰μ»¨ν…μŠ€νŠΈ

λ³€μˆ˜ yμ—μ˜ κ°’ ν• λ‹Ή

​

​

2) ν•¨μˆ˜ bar의 μ‹€ν–‰

ν•¨μˆ˜ barκ°€ μ‹€ν–‰λ˜κΈ° μ‹œμž‘ν•˜λ©΄ μƒˆλ‘œμš΄ μ‹€ν–‰ μ»¨ν…μŠ€νŠΈμ΄ μƒμ„±λœλ‹€.

μžλ°”μŠ€ν¬λ¦½νŠΈ-μ‹€ν–‰μ»¨ν…μŠ€νŠΈ

​

​

이전 ν•¨μˆ˜ foo의 μ‹€ν–‰ κ³Όμ •κ³Ό λ™μΌν•˜κ²Œ

  1. μŠ€μ½”ν”„ 체인의 생성과 μ΄ˆκΈ°ν™”,
  2. Variable Instantiation μ‹€ν–‰,
  3. this value κ²°μ •

이 순차적으둜 μ‹€ν–‰λœλ‹€.

μžλ°”μŠ€ν¬λ¦½νŠΈ-μ‹€ν–‰μ»¨ν…μŠ€νŠΈ

​이 λ‹¨κ³„μ—μ„œ console.log(x + y + z); ꡬ문의 μ‹€ν–‰ κ²°κ³ΌλŠ” xxxyyyzzzκ°€ λœλ‹€.

  • x : AO-2μ—μ„œ x 검색 μ‹€νŒ¨ → AO-1μ—μ„œ x 검색 μ‹€νŒ¨ → GOμ—μ„œ x 검색 성곡 (값은 ‘xxx’)
  • y : AO-2μ—μ„œ y 검색 μ‹€νŒ¨ → AO-1μ—μ„œ y 검색 성곡 (값은 ‘yyy’)
  • z : AO-2μ—μ„œ z 검색 성곡 (값은 ‘zzz’)

# 참고자료

http://dmitrysoshnikov.com/ecmascript/chapter-1-execution-contexts/

http://davidshariff.com/blog/what-is-the-execution-context-in-javascript/

http://jibbering.com/faq/notes/closures/