# μŠ€μ½”ν”„(Scope)

μŠ€μ½”ν”„λž€ λ³€μˆ˜μ˜ 유효 λ²”μœ„λ₯Ό μ˜λ―Έν•©λ‹ˆλ‹€.

# κΈ€λ‘œλ²Œ μŠ€μ½”ν”„

λ‹€λ₯Έ ν”„λ‘œκ·Έλž˜λ° μ–Έμ–΄μ™€λŠ” λ‹€λ₯΄κ²Œ μžλ°”μŠ€ν¬λ¦½νŠΈμ˜ λ³€μˆ˜λŠ” 유효 λ²”μœ„κ°€ μ „μ—­μœΌλ‘œ μ‹œμž‘ν•©λ‹ˆλ‹€. 예λ₯Ό λ“€μ–΄ μ•„λž˜μ™€ 같은 λ³€μˆ˜ 선언은 μžλ°”μŠ€ν¬λ¦½νŠΈλ‘œ μ ‘κ·Όν•  수 μžˆλŠ” λͺ¨λ“  μ˜μ—­μ—μ„œ 같은 값을 κ°–μŠ΅λ‹ˆλ‹€.

var a = 10;

λ§Œμ•½ ν•¨μˆ˜λ₯Ό λ§Œλ“€μ–΄ μ•„λž˜μ™€ 같이 μ ‘κ·Όν•˜λ”λΌλ„ λ™μΌν•œ 값을 좜λ ₯ν•˜κ²Œ λ©λ‹ˆλ‹€.

var a = 10;

function getA() {
  console.log(a);
}

getA(); // 10

# 둜컬 μŠ€μ½”ν”„

기본적으둜 λ³€μˆ˜μ˜ 유효 λ²”μœ„λŠ” μ „μ—­ λ²”μœ„λ₯Ό κ°–λŠ”λ‹€κ³  ν•˜μ§€λ§Œ, ν•¨μˆ˜ μ•ˆμ—μ„œ μƒˆλ‘œ μ„ μ–Έν•˜λŠ” 경우 ν•¨μˆ˜ λ‹¨μœ„μ˜ 지역 λ²”μœ„μΈ ν•¨μˆ˜ μŠ€μ½”ν”„λ₯Ό κ°–μŠ΅λ‹ˆλ‹€. μ•„λž˜ μ½”λ“œλ₯Ό λ³΄κ² μŠ΅λ‹ˆλ‹€.

var a = 10;

function getA() {
  var a = 20;
  console.log(a);
}

getA(); // 20
console.log(a); // 10

μœ„ μ½”λ“œλŠ” ν•¨μˆ˜ λ°”κΉ₯μ—μ„œ λ³€μˆ˜ aλ₯Ό μ„ μ–Έν•˜κ³  10을 λŒ€μž…ν•œ λ’€, getA()λΌλŠ” ν•¨μˆ˜λ₯Ό μ„ μ–Έν•˜λ©΄μ„œ ν•¨μˆ˜ μ•ˆμ— λ³€μˆ˜ aλ₯Ό μƒˆλ‘œ μ„ μ–Έν•˜κ³  20을 λŒ€μž…ν•œ μ½”λ“œμž…λ‹ˆλ‹€. getA() ν•¨μˆ˜λ₯Ό μ‹€ν–‰ν•˜λ©΄ ν•¨μˆ˜ μ•ˆμ˜ λ³€μˆ˜μΈ aκ°€ 20의 κ°’μœΌλ‘œ μ½˜μ†”μ— 좜λ ₯λ©λ‹ˆλ‹€. ν•¨μˆ˜μ˜ 싀행이 λλ‚˜κ³  λ‚˜μ„œ console.log(a);둜 λ‹€μ‹œ a의 값을 좜λ ₯ν•˜λ©΄ 10이 좜λ ₯λ©λ‹ˆλ‹€.

μ—¬κΈ°μ„œ λ³€μˆ˜μ˜ 유효 λ²”μœ„λŠ” ν•¨μˆ˜ λ‹¨μœ„λ‘œ ν•œμ •λœλ‹€λŠ” 것을 μ•Œ 수 μžˆμŠ΅λ‹ˆλ‹€.

# μŠ€μ½”ν”„ 체인

λ³€μˆ˜λ₯Ό 찾을 λ•Œ λ¨Όμ € μžμ‹ μ΄ μ†ν•œ μŠ€μ½”ν”„μ—μ„œ μ°Ύκ³  μ—†μœΌλ©΄ μƒμœ„ μŠ€μ½”ν”„μ—μ„œ μ°ΎλŠ” ν˜„μƒμ„ μŠ€μ½”ν”„ 체인(Scope Chain)이라고 ν•©λ‹ˆλ‹€.

κ°„λ‹¨ν•œ 예제둜 μ•žμ˜ μ½”λ“œλ₯Ό λ‹€μ‹œ μ‚΄νŽ΄λ³΄κ² μŠ΅λ‹ˆλ‹€.

// κΈ€λ‘œλ²Œ μŠ€μ½”ν”„
var a = 10;

function getA() {
  // 둜컬 μŠ€μ½”ν”„
  console.log(a);
}

getA(); // 10

getA() ν•¨μˆ˜κ°€ 싀행이 되면 λ¨Όμ € 지역 λ²”μœ„μΈ getA() ν•¨μˆ˜ μ•ˆμ—μ„œ λ³€μˆ˜ aλ₯Ό μ°Ύκ³  getA() ν•¨μˆ˜μ—λŠ” λ³€μˆ˜ aκ°€ μ—†κΈ° λ•Œλ¬Έμ— μƒμœ„ μŠ€μ½”ν”„μΈ μ „μ—­ λ²”μœ„μ—μ„œ λ³€μˆ˜ aλ₯Ό λ‹€μ‹œ μ°ΎμŠ΅λ‹ˆλ‹€.

λ‹€μŒ 예제λ₯Ό λ³΄κ² μŠ΅λ‹ˆλ‹€.

// κΈ€λ‘œλ²Œ μŠ€μ½”ν”„
var a = 10;

function outer() {
  // μ™ΈλΆ€ ν•¨μˆ˜ μŠ€μ½”ν”„
  var b = 20;

  function inner() {
    // 둜컬 ν•¨μˆ˜ μŠ€μ½”ν”„
    var c = 30;
    console.log(a);
    console.log(b);
    console.log(c);
  }
  inner();
};
outer();

// κ²°κ³Ό
// 10
// 20
// 30

μœ„μ˜ μ½”λ“œλŠ” inner() ν•¨μˆ˜μ—μ„œ a, b, c λ³€μˆ˜λ₯Ό μ°Έμ‘°ν•  λ•Œ μŠ€μ½”ν”„ 체인에 μ˜ν•΄μ„œ inner() 둜컬 ν•¨μˆ˜ μŠ€μ½”ν”„, outer() μ™ΈλΆ€ ν•¨μˆ˜ μŠ€μ½”ν”„, κΈ€λ‘œλ²Œ μŠ€μ½”ν”„μ˜ μˆœμ„œλ‘œ λ³€μˆ˜λ₯Ό μ°ΎμŠ΅λ‹ˆλ‹€.

# λ ‰μ‹œμ»¬ μŠ€μ½”ν”„

μ•žμ—μ„œ μžμ‹ μ˜ μŠ€μ½”ν”„μ—μ„œ λ³€μˆ˜λ₯Ό μ°Ύκ³  μ—†μœΌλ©΄ μƒμœ„ μŠ€μ½”ν”„μ—μ„œ μ°ΎλŠ” μŠ€μ½”ν”„ 체인에 λŒ€ν•΄ μ•Œμ•„λ³΄μ•˜μŠ΅λ‹ˆλ‹€. κ·Έλ ‡λ‹€λ©΄ 이 μƒμœ„ μŠ€μ½”ν”„λŠ” μ–΄λ–€ κΈ°μ€€μœΌλ‘œ μ •ν•˜κ²Œ λ˜λŠ” κ²ƒμΌκΉŒμš”?

μžλ°”μŠ€ν¬λ¦½νŠΈλŠ” ν•¨μˆ˜λ₯Ό μ–΄λ””μ„œ μ„ μ–Έν•˜μ˜€λŠ”μ§€μ— λ”°λΌμ„œ μƒμœ„ μŠ€μ½”ν”„λ₯Ό κ²°μ •ν•˜λŠ” λ ‰μ‹œμ»¬ μŠ€μ½”ν”„(Lexical Scope) κ·œμΉ™μ„ λ”°λ¦…λ‹ˆλ‹€.

// κΈ€λ‘œλ²Œ μŠ€μ½”ν”„
var a = 10;
var b = 20;
function getA() {
  var b = a;
  getB();
}

function getB() {
  // 둜컬 ν•¨μˆ˜ μŠ€μ½”ν”„
  console.log(b);
}

getB(); // 20
getA(); // 20

μœ„ μ½”λ“œμ—μ„œ getB() ν•¨μˆ˜λŠ” μ „μ—­ λ²”μœ„μ— μ„ μ–Έλ˜μ—ˆκΈ° λ•Œλ¬Έμ— 호좜된 μœ„μΉ˜μ™€ 상관없이 μƒμœ„ μŠ€μ½”ν”„λ‘œ κ°–λŠ” κΈ€λ‘œλ²Œ μŠ€μ½”ν”„μ™€ 자기 μžμ‹ μΈ 둜컬 ν•¨μˆ˜ μŠ€μ½”ν”„λ₯Ό μ΅œμ’… μŠ€μ½”ν”„λ₯Ό κ°–κ²Œ λ˜μ„œ λ‘˜ λ‹€ 20을 좜λ ₯ν•©λ‹ˆλ‹€.

이와 λ°˜λŒ€λ˜λŠ” κ°œλ…μΈ λ‹€μ΄λ‚˜λ―Ή μŠ€μ½”ν”„(Dynamic Scope) κ·œμΉ™μ„ λ”°λ₯΄λŠ” μ–Έμ–΄λŠ” ν•¨μˆ˜μ˜ 호좜 μœ„μΉ˜μ— 따라 μƒμœ„ μŠ€μ½”ν”„κ°€ κ²°μ •λ©λ‹ˆλ‹€.

#!/bin/sh

A=10
B=20

getA(){
  B=$A
  getB
}

getB(){
  echo $B
}

getB # 20
getA # 10

λ‹€μ΄λ‚˜λ―Ή μŠ€μ½”ν”„ κ·œμΉ™μ„ λ”°λ₯΄λŠ” μ‰˜ μŠ€ν¬λ¦½νŠΈλŠ” 20, 10이 좜λ ₯ λ©λ‹ˆλ‹€.