μŠ€μ½”ν”„

μŠ€μ½”ν”„(Scope, μœ νš¨λ²”μœ„)λŠ” μžλ°”μŠ€ν¬λ¦½νŠΈλ₯Ό ν¬ν•¨ν•œ λͺ¨λ“  ν”„λ‘œκ·Έλž˜λ° μ–Έμ–΄μ˜ 기본적인 κ°œλ…μœΌλ‘œ ν™•μ‹€ν•œ 이해가 ν•„μš”ν•˜λ‹€. λ¨Όμ € μ•„λž˜ 예제의 μ‹€ν–‰ 결과에 λŒ€ν•΄ μƒκ°ν•΄λ³΄μž.

var x = 'global';

function foo () {
  var x = 'function scope';
  console.log(x);
}

foo(); // ?
console.log(x); // ?

이름이 같은 λ³€μˆ˜ xκ°€ 쀑볡 μ„ μ–Έλ˜μ—ˆλ‹€. μ „μ—­μ—μ„œ λ³€μˆ˜ xλ₯Ό μ°Έμ‘°ν•  λ•Œ, 그리고 ν•¨μˆ˜ foo λ‚΄λΆ€μ—μ„œ λ³€μˆ˜ xλ₯Ό μ°Έμ‘°ν•  λ•Œ 이름이 μ€‘λ³΅λœ 2개의 λ³€μˆ˜ 쀑 μ–΄λ–€ λ³€μˆ˜λ₯Ό μ°Έμ‘°ν•΄μ•Ό ν•˜λŠ”κ°€? μžλ°”μŠ€ν¬λ¦½νŠΈλŠ” μ–΄λ–»κ²Œ λ³€μˆ˜λ₯Ό μ‹λ³„ν•˜λŠ” κ²ƒμΌκΉŒ?

μŠ€μ½”ν”„λŠ” μ°Έμ‘° λŒ€μƒ μ‹λ³„μž(identifier, λ³€μˆ˜, ν•¨μˆ˜μ˜ 이름과 같이 μ–΄λ–€ λŒ€μƒμ„ λ‹€λ₯Έ λŒ€μƒκ³Ό κ΅¬λΆ„ν•˜μ—¬ 식별할 수 μžˆλŠ” μœ μΌν•œ 이름)λ₯Ό μ°Ύμ•„λ‚΄κΈ° μœ„ν•œ κ·œμΉ™μ΄λ‹€. μžλ°”μŠ€ν¬λ¦½νŠΈλŠ” 이 κ·œμΉ™λŒ€λ‘œ μ‹λ³„μžλ₯Ό μ°ΎλŠ”λ‹€.

ν”„λ‘œκ·Έλž˜λ°μ€ λ³€μˆ˜λ₯Ό μ„ μ–Έν•˜κ³  값을 ν• λ‹Ήν•˜λ©° λ³€μˆ˜λ₯Ό μ°Έμ‘°ν•˜λŠ” 기본적인 κΈ°λŠ₯을 μ œκ³΅ν•˜λ©° μ΄κ²ƒμœΌλ‘œ ν”„λ‘œκ·Έλž¨μ˜ μƒνƒœλ₯Ό 관리할 수 μžˆλ‹€. λ³€μˆ˜λŠ” μ „μ—­ λ˜λŠ” μ½”λ“œ 블둝(if, for, while, try/catch λ“±)μ΄λ‚˜ ν•¨μˆ˜ 내에 μ„ μ–Έν•˜λ©° μ½”λ“œ λΈ”λ‘μ΄λ‚˜ ν•¨μˆ˜λŠ” 쀑첩될 수 μžˆλ‹€. μ‹λ³„μžλŠ” μžμ‹ μ΄ μ–΄λ””μ—μ„œ μ„ μ–ΈλλŠ”μ§€μ— μ˜ν•΄ μžμ‹ μ΄ μœ νš¨ν•œ(λ‹€λ₯Έ μ½”λ“œκ°€ μžμ‹ μ„ μ°Έμ‘°ν•  수 μžˆλŠ”) λ²”μœ„λ₯Ό κ°–λŠ”λ‹€.

μœ„ μ˜ˆμ œμ—μ„œ 전역에 μ„ μ–Έλœ λ³€μˆ˜ xλŠ” 어디에든 μ°Έμ‘°ν•  수 μžˆλ‹€. ν•˜μ§€λ§Œ ν•¨μˆ˜ foo λ‚΄μ—μ„œ μ„ μ–Έλœ λ³€μˆ˜ xλŠ” ν•¨μˆ˜ foo λ‚΄λΆ€μ—μ„œλ§Œ μ°Έμ‘°ν•  수 있고 ν•¨μˆ˜ μ™ΈλΆ€μ—μ„œλŠ” μ°Έμ‘°ν•  수 μ—†λ‹€. μ΄λŸ¬ν•œ κ·œμΉ™μ„ μŠ€μ½”ν”„λΌκ³  ν•œλ‹€.
λ§Œμ•½ μŠ€μ½”ν”„κ°€ μ—†λ‹€λ©΄ μ–΄λ–»κ²Œ 될까? μŠ€μ½”ν”„κ°€ μ—†λ‹€λ©΄ 같은 μ‹λ³„μž 이름은 μΆ©λŒμ„ μΌμœΌν‚€λ―€λ‘œ ν”„λ‘œκ·Έλž¨ μ „μ²΄μ—μ„œ ν•˜λ‚˜λ°–μ— μ‚¬μš©ν•  수 μ—†λ‹€. 디렉터리가 μ—†λŠ” 컴퓨터λ₯Ό μƒκ°ν•΄λ³΄μž. 디렉터리가 μ—†λ‹€λ©΄ 같은 이름을 κ°–λŠ” νŒŒμΌμ„ ν•˜λ‚˜λ°–μ— λ§Œλ“€ 수 μ—†λ‹€. μŠ€μ½”ν”„λ„ 이와 같이 μ‹λ³„μž μ΄λ¦„μ˜ μΆ©λŒμ„ λ°©μ§€ν•œλ‹€.

μŠ€μ½”ν”„μ˜ ꡬ뢄

μžλ°”μŠ€ν¬λ¦½νŠΈμ—μ„œ μŠ€μ½”ν”„λ₯Ό ꡬ뢄해보면 λ‹€μŒκ³Ό 같이 2κ°€μ§€λ‘œ λ‚˜λˆŒ 수 μžˆλ‹€.

μ „μ—­ μŠ€μ½”ν”„ (Global scope)
μ½”λ“œ μ–΄λ””μ—μ„œλ“ μ§€ μ°Έμ‘°ν•  수 μžˆλ‹€.

지역 μŠ€μ½”ν”„ (Local scope or Function-level scope)
ν•¨μˆ˜ μ½”λ“œ 블둝이 λ§Œλ“  μŠ€μ½”ν”„λ‘œ ν•¨μˆ˜ μžμ‹ κ³Ό ν•˜μœ„ ν•¨μˆ˜μ—μ„œλ§Œ μ°Έμ‘°ν•  수 μžˆλ‹€. λͺ¨λ“  λ³€μˆ˜λŠ” μŠ€μ½”ν”„λ₯Ό κ°–λŠ”λ‹€.

λ³€μˆ˜μ˜ κ΄€μ μ—μ„œ μŠ€μ½”ν”„λ₯Ό κ΅¬λΆ„ν•˜λ©΄ λ‹€μŒκ³Ό 같이 2κ°€μ§€λ‘œ λ‚˜λˆŒ 수 μžˆλ‹€.

μ „μ—­ λ³€μˆ˜ (Global variable)
μ „μ—­μ—μ„œ μ„ μ–Έλœ λ³€μˆ˜μ΄λ©° 어디에든 μ°Έμ‘°ν•  수 μžˆλ‹€.

지역 λ³€μˆ˜ (Local variable)
지역(ν•¨μˆ˜) λ‚΄μ—μ„œ μ„ μ–Έλœ λ³€μˆ˜μ΄λ©° κ·Έ 지역과 κ·Έ μ§€μ—­μ˜ ν•˜λΆ€ μ§€μ—­μ—μ„œλ§Œ μ°Έμ‘°ν•  수 μžˆλ‹€.
λ³€μˆ˜λŠ” μ„ μ–Έ μœ„μΉ˜(μ „μ—­ λ˜λŠ” 지역)에 μ˜ν•΄ μŠ€μ½”ν”„λ₯Ό κ°€μ§€κ²Œ λœλ‹€. 즉, μ „μ—­μ—μ„œ μ„ μ–Έλœ λ³€μˆ˜λŠ” μ „μ—­ μŠ€μ½”ν”„λ₯Ό κ°–λŠ” μ „μ—­ λ³€μˆ˜μ΄κ³ , 지역(μžλ°”μŠ€ν¬λ¦½νŠΈμ˜ 경우 ν•¨μˆ˜ λ‚΄λΆ€)μ—μ„œ μ„ μ–Έλœ λ³€μˆ˜λŠ” 지역 μŠ€μ½”ν”„λ₯Ό κ°–λŠ” 지역 λ³€μˆ˜κ°€ λœλ‹€.

μ „μ—­ μŠ€μ½”ν”„λ₯Ό κ°–λŠ” μ „μ—­ λ³€μˆ˜λŠ” μ „μ—­(μ½”λ“œ μ–΄λ””μ„œλ“ μ§€)μ—μ„œ μ°Έμ‘°ν•  수 μžˆλ‹€. 지역(ν•¨μˆ˜ λ‚΄λΆ€)μ—μ„œ μ„ μ–Έλœ 지역 λ³€μˆ˜λŠ” κ·Έ 지역과 κ·Έ μ§€μ—­μ˜ ν•˜λΆ€ μ§€μ—­μ—μ„œλ§Œ μ°Έμ‘°ν•  수 μžˆλ‹€.

μžλ°”μŠ€ν¬λ¦½νŠΈ μŠ€μ½”ν”„μ˜ νŠΉμ§•

μžλ°”μŠ€ν¬λ¦½νŠΈλŠ” λŒ€λΆ€λΆ„ μ–Έμ–΄μ˜ 블둝 레벨 μŠ€μ½”ν”„(block-level scope)λ₯Ό λ”°λ₯΄λŠ” λŒ€μ‹ , ν•¨μˆ˜ 레벨 μŠ€μ½”ν”„(function-level scope)λ₯Ό λ”°λ₯Έλ‹€.
ν•¨μˆ˜ 레벨 μŠ€μ½”ν”„λž€ ν•¨μˆ˜ μ½”λ“œ 블둝 λ‚΄μ—μ„œ μ„ μ–Έλœ λ³€μˆ˜λŠ” ν•¨μˆ˜ μ½”λ“œ 블둝 λ‚΄μ—μ„œλ§Œ μœ νš¨ν•˜κ³  ν•¨μˆ˜ μ™ΈλΆ€μ—μ„œλŠ” μœ νš¨ν•˜μ§€ μ•Šλ‹€(μ°Έμ‘°ν•  수 μ—†λ‹€)λŠ” 것이닀.

 

var x = 0;
{
  var x = 1;
  console.log(x); // 1
}
console.log(x);   // 1

let y = 0;
{
  let y = 1;
  console.log(y); // 1
}
console.log(y);   // 0

μ „μ—­ μŠ€μ½”ν”„(Global scope)

전역에 λ³€μˆ˜λ₯Ό μ„ μ–Έν•˜λ©΄ 이 λ³€μˆ˜λŠ” μ–΄λ””μ„œλ“ μ§€ μ°Έμ‘°ν•  수 μžˆλŠ” μ „μ—­ μŠ€μ½”ν”„λ₯Ό κ°–λŠ” μ „μ—­ λ³€μˆ˜κ°€ λœλ‹€. var ν‚€μ›Œλ“œλ‘œ μ„ μ–Έν•œ μ „μ—­ λ³€μˆ˜λŠ” μ „μ—­ 객체(Global Object) window의 ν”„λ‘œνΌν‹°μ΄λ‹€.

var global = 'global';

function foo() {
  var local = 'local';
  console.log(global);
  console.log(local);
}
foo();

console.log(global);
console.log(local); // Uncaught ReferenceError: local is not defined

λ³€μˆ˜ global은 ν•¨μˆ˜ μ˜μ—­ λ°–μ˜ μ „μ—­μ—μ„œ μ„ μ–Έλ˜μ—ˆλ‹€. μžλ°”μŠ€ν¬λ¦½νŠΈλŠ” 타 μ–Έμ–΄μ™€λŠ” 달리 νŠΉλ³„ν•œ μ‹œμž‘μ (Entry point)이 μ—†μ–΄μ„œ μœ„ μ½”λ“œμ™€ 같이 전역에 λ³€μˆ˜λ‚˜ ν•¨μˆ˜λ₯Ό μ„ μ–Έν•˜κΈ° 쉽닀.
μ „μ—­ λ³€μˆ˜μ˜ μ‚¬μš©μ€ λ³€μˆ˜ 이름이 쀑볡될 수 있고, μ˜λ„μΉ˜ μ•Šμ€ μž¬ν• λ‹Ήμ— μ˜ν•œ μƒνƒœ λ³€ν™”λ‘œ μ½”λ“œλ₯Ό μ˜ˆμΈ‘ν•˜κΈ° μ–΄λ ΅κ²Œ λ§Œλ“œλ―€λ‘œ μ‚¬μš©μ„ μ–΅μ œν•˜μ—¬μ•Ό ν•œλ‹€.

λΉ„ 블둝 레벨 μŠ€μ½”ν”„(Non block-level scope)

if (true) {
  var x = 5;
}
console.log(x);

λ³€μˆ˜ xλŠ” μ½”λ“œ 블둝 λ‚΄μ—μ„œ μ„ μ–Έλ˜μ—ˆλ‹€. ν•˜μ§€λ§Œ μžλ°”μŠ€ν¬λ¦½νŠΈλŠ” 블둝 레벨 μŠ€μ½”ν”„λ₯Ό μ‚¬μš©ν•˜μ§€ μ•ŠμœΌλ―€λ‘œ ν•¨μˆ˜ λ°–μ—μ„œ μ„ μ–Έλœ λ³€μˆ˜λŠ” μ½”λ“œ 블둝 λ‚΄μ—μ„œ μ„ μ–Έλ˜μ—ˆλ‹€ν• μ§€λΌλ„ λͺ¨λ‘ μ „μ—­ μŠ€μ½”ν”„μ„ κ°–κ²Œλœλ‹€. λ”°λΌμ„œ λ³€μˆ˜ xλŠ” μ „μ—­ λ³€μˆ˜μ΄λ‹€.

ν•¨μˆ˜ 레벨 μŠ€μ½”ν”„(Function-level scope)

var a = 10;     // μ „μ—­λ³€μˆ˜

(function () {
  var b = 20;   // μ§€μ—­λ³€μˆ˜
})();

console.log(a); // 10
console.log(b); // "b" is not defined

μžλ°”μŠ€ν¬λ¦½νŠΈλŠ” ν•¨μˆ˜ 레벨 μŠ€μ½”ν”„λ₯Ό μ‚¬μš©ν•œλ‹€. 즉, ν•¨μˆ˜ λ‚΄μ—μ„œ μ„ μ–Έλœ λ§€κ°œλ³€μˆ˜μ™€ λ³€μˆ˜λŠ” ν•¨μˆ˜ μ™ΈλΆ€μ—μ„œλŠ” μœ νš¨ν•˜μ§€ μ•Šλ‹€. λ”°λΌμ„œ λ³€μˆ˜ bλŠ” 지역 λ³€μˆ˜μ΄λ‹€.

var x = 'global';

function foo() {
  var x = 'local';
  console.log(x);
}

foo();          // local
console.log(x); // global

μ „μ—­λ³€μˆ˜ x와 μ§€μ—­λ³€μˆ˜ xκ°€ 쀑볡 μ„ μ–Έλ˜μ—ˆλ‹€. μ „μ—­ μ˜μ—­μ—μ„œλŠ” μ „μ—­λ³€μˆ˜λ§Œμ΄ μ°Έμ‘° κ°€λŠ₯ν•˜κ³  ν•¨μˆ˜ λ‚΄ 지역 μ˜μ—­μ—μ„œλŠ” μ „μ—­κ³Ό 지역 λ³€μˆ˜ λͺ¨λ‘ μ°Έμ‘° κ°€λŠ₯ν•˜λ‚˜ μœ„ μ˜ˆμ œμ™€ 같이 λ³€μˆ˜λͺ…이 μ€‘λ³΅λœ 경우, μ§€μ—­λ³€μˆ˜λ₯Ό μš°μ„ ν•˜μ—¬ μ°Έμ‘°ν•œλ‹€.

λ‹€μŒμ€ ν•¨μˆ˜ 내에 μ‘΄μž¬ν•˜λŠ” ν•¨μˆ˜μΈ λ‚΄λΆ€ ν•¨μˆ˜μ˜ 경우λ₯Ό μ‚΄νŽ΄λ³΄μž.

var x = 'global';

function foo() {
  var x = 'local';
  console.log(x);

  function bar() {  // λ‚΄λΆ€ν•¨μˆ˜
    console.log(x); // ?
  }

  bar();
}
foo();
console.log(x); // ?

λ‚΄λΆ€ν•¨μˆ˜λŠ” μžμ‹ μ„ ν¬ν•¨ν•˜κ³  μžˆλŠ” μ™ΈλΆ€ν•¨μˆ˜μ˜ λ³€μˆ˜μ— μ ‘κ·Όν•  수 μžˆλ‹€. μ΄λŠ” 맀우 μœ μš©ν•˜λ‹€. ν΄λ‘œμ €μ—μ„œμ™€ 같이 λ‚΄λΆ€ν•¨μˆ˜κ°€ 더 였래 μƒμ‘΄ν•˜λŠ” 경우, 타 μ–Έμ–΄μ™€λŠ” λ‹€λ₯Έ μ›€μ§μž„μ„ 보인닀.

ν•¨μˆ˜ barμ—μ„œ μ°Έμ‘°ν•˜λŠ” λ³€μˆ˜ xλŠ” ν•¨μˆ˜ fooμ—μ„œ μ„ μ–Έλœ μ§€μ—­λ³€μˆ˜μ΄λ‹€. μ΄λŠ” μ‹€ν–‰ μ»¨ν…μŠ€νŠΈμ˜ μŠ€μ½”ν”„ 체인에 μ˜ν•΄ μ°Έμ‘° μˆœμœ„μ—μ„œ μ „μ—­λ³€μˆ˜ xκ°€ λ’€λ‘œ λ°€λ ΈκΈ° λ•Œλ¬Έμ΄λ‹€.

var x = 10;

function foo() {
  x = 100;
  console.log(x);
}
foo();
console.log(x); // ?

ν•¨μˆ˜(지역) μ˜μ—­μ—μ„œ μ „μ—­λ³€μˆ˜λ₯Ό μ°Έμ‘°ν•  수 μžˆμœΌλ―€λ‘œ μ „μ—­λ³€μˆ˜μ˜ 값도 λ³€κ²½ν•  수 μžˆλ‹€. λ‚΄λΆ€ ν•¨μˆ˜μ˜ 경우, μ „μ—­λ³€μˆ˜λŠ” λ¬Όλ‘  μƒμœ„ ν•¨μˆ˜μ—μ„œ μ„ μ–Έν•œ λ³€μˆ˜μ— μ ‘κ·Ό/변경이 κ°€λŠ₯ν•˜λ‹€.

var x = 10;

function foo(){
  var x = 100;
  console.log(x);

  function bar(){   // λ‚΄λΆ€ν•¨μˆ˜
    x = 1000;
    console.log(x); // ?
  }

  bar();
}
foo();
console.log(x); // ?

쀑첩 μŠ€μ½”ν”„λŠ” κ°€μž₯ μΈμ ‘ν•œ 지역을 μš°μ„ ν•˜μ—¬ μ°Έμ‘°ν•œλ‹€.

var foo = function ( ) {

  var a = 3, b = 5;

  var bar = function ( ) {
    var b = 7, c = 11;

// 이 μ‹œμ μ—μ„œ aλŠ” 3, bλŠ” 7, cλŠ” 11

    a += b + c;

// 이 μ‹œμ μ—μ„œ aλŠ” 21, bλŠ” 7, cλŠ” 11

  };

// 이 μ‹œμ μ—μ„œ aλŠ” 3, bλŠ” 5, cλŠ” not defined

  bar( );

// 이 μ‹œμ μ—μ„œ aλŠ” 21, bλŠ” 5

};

λ ‰μ‹œμ»¬ μŠ€μ½”ν”„(Lexical scope)

var x = 1;

function foo() {
  var x = 10;
  bar();
}

function bar() {
  console.log(x);
}

foo(); // ?
bar(); // ?

μœ„ 예제의 μ‹€ν–‰ κ²°κ³ΌλŠ” ν•¨μˆ˜ bar의 μƒμœ„ μŠ€μ½”ν”„κ°€ 무엇인지에 따라 κ²°μ •λœλ‹€. 두가지 νŒ¨ν„΄μ„ μ˜ˆμΈ‘ν•  수 μžˆλŠ”λ° μ²«λ²ˆμ§ΈλŠ” ν•¨μˆ˜λ₯Ό μ–΄λ””μ„œ ν˜ΈμΆœν•˜μ˜€λŠ”μ§€μ— 따라 μƒμœ„ μŠ€μ½”ν”„λ₯Ό κ²°μ •ν•˜λŠ” 것이고 λ‘λ²ˆμ§ΈλŠ” ν•¨μˆ˜λ₯Ό μ–΄λ””μ„œ μ„ μ–Έν•˜μ˜€λŠ”μ§€μ— 따라 μƒμœ„ μŠ€μ½”ν”„λ₯Ό κ²°μ •ν•˜λŠ” 것이닀. 첫번째 λ°©μ‹μœΌλ‘œ ν•¨μˆ˜μ˜ μƒμœ„ μŠ€μ½”ν”„λ₯Ό κ²°μ •ν•œλ‹€λ©΄ ν•¨μˆ˜ bar의 μƒμœ„ μŠ€μ½”ν”„λŠ” ν•¨μˆ˜ foo와 전역일 것이고, λ‘λ²ˆμ§Έ λ°©μ‹μœΌλ‘œ ν•¨μˆ˜μ˜ μŠ€μ½”ν”„λ₯Ό κ²°μ •ν•œλ‹€λ©΄ ν•¨μˆ˜ bar의 μŠ€μ½”ν”„λŠ” 전역일 것이닀.

ν”„λ‘œκ·Έλž˜λ° μ–Έμ–΄λŠ” 이 두가지 방식 쀑 ν•˜λ‚˜μ˜ λ°©μ‹μœΌλ‘œ ν•¨μˆ˜μ˜ μƒμœ„ μŠ€μ½”ν”„λ₯Ό κ²°μ •ν•œλ‹€. 첫번째 방식을 동적 μŠ€μ½”ν”„(Dynamic scope)라 ν•˜κ³ , λ‘λ²ˆμ§Έ 방식을 λ ‰μ‹œμ»¬ μŠ€μ½”ν”„(Lexical scope) λ˜λŠ” 정적 μŠ€μ½”ν”„(Static scope)라 ν•œλ‹€. μžλ°”μŠ€ν¬λ¦½νŠΈλ₯Ό λΉ„λ‘―ν•œ λŒ€λΆ€λΆ„μ˜ ν”„λ‘œκ·Έλž˜λ° μ–Έμ–΄λŠ” λ ‰μ‹œμ»¬ μŠ€μ½”ν”„λ₯Ό λ”°λ₯Έλ‹€.

λ ‰μ‹œμ»¬ μŠ€μ½”ν”„λŠ” ν•¨μˆ˜λ₯Ό μ–΄λ””μ„œ ν˜ΈμΆœν•˜λŠ”μ§€κ°€ μ•„λ‹ˆλΌ 어디에 μ„ μ–Έν•˜μ˜€λŠ”μ§€μ— 따라 κ²°μ •λœλ‹€. μžλ°”μŠ€ν¬λ¦½νŠΈλŠ” λ ‰μ‹œμ»¬ μŠ€μ½”ν”„λ₯Ό λ”°λ₯΄λ―€λ‘œ ν•¨μˆ˜λ₯Ό μ„ μ–Έν•œ μ‹œμ μ— μƒμœ„ μŠ€μ½”ν”„κ°€ κ²°μ •λœλ‹€. ν•¨μˆ˜λ₯Ό μ–΄λ””μ—μ„œ ν˜ΈμΆœν•˜μ˜€λŠ”μ§€λŠ” μŠ€μ½”ν”„ 결정에 μ•„λ¬΄λŸ° 의미λ₯Ό 주지 μ•ŠλŠ”λ‹€. μœ„ 예제의 ν•¨μˆ˜ barλŠ” 전역에 μ„ μ–Έλ˜μ—ˆλ‹€. λ”°λΌμ„œ ν•¨μˆ˜ bar의 μƒμœ„ μŠ€μ½”ν”„λŠ” μ „μ—­ μŠ€μ½”ν”„μ΄κ³  μœ„ μ˜ˆμ œλŠ” μ „μ—­ λ³€μˆ˜ x의 κ°’ 1을 λ‘λ²ˆ 좜λ ₯ν•œλ‹€.

암묡적 μ „μ—­

var x = 10; // μ „μ—­ λ³€μˆ˜

function foo () {
  // μ„ μ–Έν•˜μ§€ μ•Šμ€ μ‹λ³„μž
  y = 20;
  console.log(x + y);
}

foo(); // 30

μœ„ 예제의 yλŠ” μ„ μ–Έν•˜μ§€ μ•Šμ€ μ‹λ³„μžμ΄λ‹€. λ”°λΌμ„œ y = 20이 μ‹€ν–‰λ˜λ©΄ μ°Έμ‘° μ—λŸ¬κ°€ λ°œμƒν•  κ²ƒμ²˜λŸΌ 보인닀. ν•˜μ§€λ§Œ μ„ μ–Έν•˜μ§€ μ•Šμ€ μ‹λ³„μž yλŠ” 마치 μ„ μ–Έλœ λ³€μˆ˜μ²˜λŸΌ λ™μž‘ν•œλ‹€. μ΄λŠ” μ„ μ–Έν•˜μ§€ μ•Šμ€ μ‹λ³„μžμ— 값을 ν• λ‹Ήν•˜λ©΄ μ „μ—­ 객체의 ν”„λ‘œνΌν‹°κ°€ 되기 λ•Œλ¬Έμ΄λ‹€.

foo ν•¨μˆ˜κ°€ 호좜되면 μžλ°”μŠ€ν¬λ¦½νŠΈ 엔진은 λ³€μˆ˜ y에 값을 ν• λ‹Ήν•˜κΈ° μœ„ν•΄ λ¨Όμ € μŠ€μ½”ν”„ 체인을 톡해 μ„ μ–Έλœ λ³€μˆ˜μΈμ§€ ν™•μΈν•œλ‹€. μ΄λ•Œ foo ν•¨μˆ˜μ˜ μŠ€μ½”ν”„μ™€ μ „μ—­ μŠ€μ½”ν”„ μ–΄λ””μ—μ„œλ„ λ³€μˆ˜ y의 선언을 찾을 수 μ—†μœΌλ―€λ‘œ μ°Έμ‘° μ—λŸ¬κ°€ λ°œμƒν•΄μ•Ό ν•˜μ§€λ§Œ μžλ°”μŠ€ν¬λ¦½νŠΈ 엔진은 y = 20을 window.y = 20으둜 ν•΄μ„ν•˜μ—¬ ν”„λ‘œνΌν‹°λ₯Ό 동적 μƒμ„±ν•œλ‹€. κ²°κ΅­ yλŠ” μ „μ—­ 객체의 ν”„λ‘œνΌν‹°κ°€ λ˜μ–΄ 마치 μ „μ—­ λ³€μˆ˜μ²˜λŸΌ λ™μž‘ν•œλ‹€. μ΄λŸ¬ν•œ ν˜„μƒμ„ 암묡적 μ „μ—­(implicit global)이라 ν•œλ‹€.

ν•˜μ§€λ§Œ yλŠ” λ³€μˆ˜ 선언없이 단지 μ „μ—­ 객체의 ν”„λ‘œνΌν‹°λ‘œ μΆ”κ°€λ˜μ—ˆμ„ 뿐이닀. λ”°λΌμ„œ yλŠ” λ³€μˆ˜κ°€ μ•„λ‹ˆλ‹€. λ”°λΌμ„œ λ³€μˆ˜κ°€ μ•„λ‹Œ yλŠ” λ³€μˆ˜ ν˜Έμ΄μŠ€νŒ…μ΄ λ°œμƒν•˜μ§€ μ•ŠλŠ”λ‹€.

// μ „μ—­ λ³€μˆ˜ xλŠ” ν˜Έμ΄μŠ€νŒ…μ΄ λ°œμƒν•œλ‹€.
console.log(x); // undefined
// μ „μ—­ λ³€μˆ˜κ°€ μ•„λ‹ˆλΌ 단지 μ „μ—­ ν”„λ‘œνΌν‹°μΈ yλŠ” ν˜Έμ΄μŠ€νŒ…μ΄ λ°œμƒν•˜μ§€ μ•ŠλŠ”λ‹€.
console.log(y); // ReferenceError: y is not defined

var x = 10; // μ „μ—­ λ³€μˆ˜

function foo () {
  // μ„ μ–Έν•˜μ§€ μ•Šμ€ λ³€μˆ˜
  y = 20;
  console.log(x + y);
}

foo(); // 30

λ˜ν•œ λ³€μˆ˜κ°€ μ•„λ‹ˆλΌ 단지 ν”„λ‘œνΌν‹°μΈ yλŠ” delete μ—°μ‚°μžλ‘œ μ‚­μ œν•  수 μžˆλ‹€. μ „μ—­ λ³€μˆ˜λŠ” ν”„λ‘œνΌν‹°μ΄μ§€λ§Œ delete μ—°μ‚°μžλ‘œ μ‚­μ œν•  수 μ—†λ‹€.\

var x = 10; // μ „μ—­ λ³€μˆ˜

function foo () {
  // μ„ μ–Έν•˜μ§€ μ•Šμ€ λ³€μˆ˜
  y = 20;
  console.log(x + y);
}

foo(); // 30

console.log(window.x); // 10
console.log(window.y); // 20

delete x; // μ „μ—­ λ³€μˆ˜λŠ” μ‚­μ œλ˜μ§€ μ•ŠλŠ”λ‹€.
delete y; // ν”„λ‘œνΌν‹°λŠ” μ‚­μ œλœλ‹€.

console.log(window.x); // 10
console.log(window.y); // undefined

μŠ€μ½”ν”„ 체인

scopeλŠ” μ‹λ³„μžμ— λŒ€ν•œ 유효 λ²”μœ„λ₯Ό λ‚˜νƒ€λ‚Έλ‹€. μ–΄λ–€ 경계 A의 μ™ΈλΆ€μ—μ„œ μ„ μ–Έν•œ λ³€μˆ˜λŠ” A의 외뢀뿐 μ•„λ‹ˆλΌ A의 λ‚΄λΆ€μ—μ„œλ„ 접근이 κ°€λŠ₯ν•˜μ§€λ§Œ, A의 λ‚΄λΆ€μ—μ„œ μ„ μ–Έν•œ λ³€μˆ˜λŠ” 였직 A의 λ‚΄λΆ€μ—μ„œλ§Œ μ ‘κ·Όν•  수 μžˆλ‹€. μ΄λŸ¬ν•œ μ‹λ³„μžμ˜ μœ νš¨λ²”μ˜λ₯Ό μ•ˆμ—μ„œλΆ€ν„° λ°”κΉ₯으둜 μ°¨λ‘€λ‘œ κ²€μƒ‰ν•΄λ‚˜κ°€λŠ” 것을 μŠ€μ½”ν”„ 체인이라고 λΆ€λ₯Έλ‹€. μ΄λ•Œ outerEnvironmentReferenceλŠ” ν˜„μž¬ 호좜된 ν•¨μˆ˜κ°€ 선언될 λ‹Ήμ‹œμ˜ L.Eλ₯Ό μ°Έμ‘°ν•˜κ²Œλ˜λŠ”λ°, μ€‘μš”ν•œ 점은 κ³Όκ±° λ‹Ήμ‹œ μ„ μ–Έλœ μ‹œμ μ΄λ‹€.

var x = 1;

function foo(){
  var x = 10;
  bar();
}

function bar(){
  console.log(x);
}

foo();  // 1
bar();  // 1

λ‹€μŒ μ½”λ“œμ˜ foo()와 bar()의 좜λ ₯값은 1둜 λ™μΌν•œλ°, κ·Έ μ΄μœ λŠ” function barκ°€ μ„ μ–Έλœ μ‹œμ μ˜ xλŠ” μ „μ—­ λ³€μˆ˜μΈ xλ₯Ό λ°”λΌλ³΄κ²Œ λœλ‹€. 즉, this처럼 ν•¨μˆ˜λ₯Ό μ–΄λ””μ„œ ν˜ΈμΆœν–ˆλŠ”μ§€ 영ν–₯을 λ°›λŠ” 것이 μ•„λ‹ˆλΌ ν•¨μˆ˜λ₯Ό μ–΄λ””μ—μ„œ μ •μ˜ν–ˆλŠ”μ§€μ— 따라 μƒμœ„ μŠ€μ½”ν”„λ₯Ό κ²°μ •ν•œλ‹€. ν•¨μˆ˜κ°€ 호좜된 μœ„μΉ˜λŠ” μƒμœ„ μŠ€μ½”ν”„ 결정에 μ–΄λ– ν•œ 영ν–₯도 주지 μ•ŠλŠ”λ‹€. 즉, ν•¨μˆ˜μ˜ μƒμœ„ μŠ€μ½”ν”„λŠ” μ–Έμ œλ‚˜ μžμ‹ μ΄ μ •μ˜λœ μŠ€μ½”ν”„λ‹€. ν•¨μˆ˜ μ„ μ–Έλ¬ΈμœΌλ‘œ μ •μ˜λœ bar ν•¨μˆ˜λŠ” μ „μ—­μ—μ„œ μ •μ˜λœ ν•¨μˆ˜λ‹€. κ·ΈλŸ¬λ―€λ‘œ μ „μ—­ μ½”λ“œκ°€ μ‹€ν–‰λ˜κΈ° 전에 λ¨Όμ € ν‰κ°€λ˜μ–΄ ν•¨μˆ˜ 객체λ₯Ό μƒμ„±ν•œλ‹€. μ΄λ•Œ μƒμ„±λœ bar ν•¨μˆ˜ κ°μ²΄λŠ” μ „μ—­ μŠ€μ½”ν”„λ₯Ό κΈ°μ–΅ν•œλ‹€. 그리고 bar ν•¨μˆ˜κ°€ 호좜되면 호좜된 곳이 어디인지 관계없이 μ–Έμ œλ‚˜ μžμ‹ μ΄ κΈ°μ–΅ν•˜κ³  μžˆλŠ” μ „μ—­ μŠ€μ½”ν”„λ₯Ό μƒμœ„ μŠ€μ½”ν”„λ‘œ μ‚¬μš©ν•œλ‹€.

μΆ”κ°€λ‘œ 읽으면 쒋을 κΈ€

 

[JS] 6. ν•¨μˆ˜ μŠ€μ½”ν”„ & 블둝 μŠ€μ½”ν”„ & λ ‰μ‹œμ»¬ μŠ€μ½”ν”„

GitHub - yjs03057/33-js-concepts: λͺ¨λ“  μžλ°”μŠ€ν¬λ¦½νŠΈ κ°œλ°œμžκ°€ μ•Œμ•„μ•Ό ν•˜λŠ” 33가지 κ°œλ… λͺ¨λ“  μžλ°”μŠ€ν¬λ¦½νŠΈ κ°œλ°œμžκ°€ μ•Œμ•„μ•Ό ν•˜λŠ” 33가지 κ°œλ…. Contribute to yjs03057/33-js-concepts development by creatin..

eun-ng.tistory.com

Reference

 

Scope | PoiemaWeb

μŠ€μ½”ν”„λŠ” μ°Έμ‘° λŒ€μƒ μ‹λ³„μž(identifier, λ³€μˆ˜, ν•¨μˆ˜μ˜ 이름과 같이 μ–΄λ–€ λŒ€μƒμ„ λ‹€λ₯Έ λŒ€μƒκ³Ό 식별할 수 μžˆλŠ” μœ μΌν•œ 이름)λ₯Ό μ°Ύμ•„λ‚΄κΈ° μœ„ν•œ κ·œμΉ™μœΌλ‘œ μžλ°”μŠ€ν¬λ¦½νŠΈλŠ” 이 κ·œμΉ™λŒ€λ‘œ μ‹λ³„μžλ₯Ό μ°ΎλŠ”λ‹€.

poiemaweb.com

λ³΅μ‚¬ν–ˆμŠ΅λ‹ˆλ‹€!