Skip to content

Latest commit

Β 

History

History
191 lines (133 loc) Β· 6.63 KB

File metadata and controls

191 lines (133 loc) Β· 6.63 KB

πŸ’» Scope


πŸ‘¨πŸ»β€πŸ’» μŠ€μ½”ν”„(Scope)

  • μŠ€μ½”ν”„(Scope, μœ νš¨λ²”μœ„)λŠ” μžλ°”μŠ€ν¬λ¦½νŠΈλ₯Ό ν¬ν•¨ν•œ λͺ¨λ“  ν”„λ‘œκ·Έλž˜λ° μ–Έμ–΄μ˜ 기본적인 κ°œλ…μ΄λ‹€.
  • μŠ€μ½”ν”„λŠ” μ°Έμ‘° λŒ€μƒ μ‹λ³„μž(identifier, λ³€μˆ˜, ν•¨μˆ˜μ˜ 이름과 같이 μ–΄λ–€ λŒ€μƒμ„ λ‹€λ₯Έ λŒ€μƒκ³Ό κ΅¬λΆ„ν•˜μ—¬ 식별할 수 μžˆλŠ” μœ μΌν•œ 이름)λ₯Ό μ°Ύμ•„λ‚΄κΈ° μœ„ν•œ κ·œμΉ™μ΄λ‹€.
  • 즉, μ–΄λ–€ λ³€μˆ˜λ₯Ό μ‚¬μš©ν•˜κ±°λ‚˜ ν•¨μˆ˜λ₯Ό ν˜ΈμΆœν•˜λ €κ³  ν•  λ•Œ ν•΄λ‹Ήν•˜λŠ” μ‹λ³„μžλ‘œ μ‚¬μš©ν•˜λŠ”λ°, κ·Έ μ‹λ³„μžλ₯Ό κ²€μƒ‰ν•˜λŠ” λ©”μ»€λ‹ˆμ¦˜μ΄λΌκ³  μ΄ν•΄ν•˜λ©΄ λœλ‹€.

let x = 'global';

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

foo();
console.log(x);

  • μœ„ μ˜ˆμ œμ—μ„œ 전역에 μ„ μ–Έν•œ λ³€μˆ˜ xλŠ” 어디에든 μ°Έμ‘°ν•  수 μžˆλ‹€. ν•˜μ§€λ§Œ ν•¨μˆ˜ foo λ‚΄μ—μ„œ μ„ μ–Έλœ λ³€μˆ˜ xλŠ” ν•¨μˆ˜ foo λ‚΄μ—μ„œλ§Œ μ°Έμ‘°ν•  수 μžˆλ”°. μ΄λŸ¬ν•œ κ·œμΉ™μ„ μŠ€μ½”ν”„λΌκ³  ν•œλ‹€.

πŸ‘¨πŸ»β€πŸ’» μŠ€μ½”ν”„μ˜ ꡬ뢄

πŸƒ μžλ°”μŠ€ν¬λ¦½νŠΈμ—μ„œ μŠ€μ½”ν”„

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

πŸƒ λ³€μˆ˜ κ΄€μ μ—μ„œ μŠ€μ½”ν”„

  • μ „μ—­ λ³€μˆ˜(Global variable): μ „μ—­μ—μ„œ μ„ μ–Έλœ λ³€μˆ˜μ΄λ©° 어디에든 μ°Έμ‘°ν•  수 μžˆλ‹€.
  • 지역 λ³€μˆ˜(Local variable): 지역 λ‚΄μ—μ„œ μ„ μ–Έλœ λ³€μˆ˜μ΄λ©° κ·Έ 지역과 κ·Έ μ§€μ—­μ˜ ν•˜λΆ€ μ§€μ—­μ—μ„œλ§Œ μ°Έμ‘°ν•  수 μž‡λ‹€.

πŸ‘¨πŸ»β€πŸ’» μžλ°”μŠ€ν¬λ¦½νŠΈ μŠ€μ½”ν”„μ˜ νŠΉμ§•

  • λŒ€λΆ€λΆ„μ˜ C-family languageλŠ” 블둝 레벨 μŠ€μ½”ν”„(block-level-scope)λ₯Ό λ”°λ₯Έλ‹€.
  • 블둝 레벨 μŠ€μ½”ν”„λž€, μ½”λ“œ 블둝({ ... })λ‚΄μ—μ„œ μœ νš¨ν•œ μŠ€μ½”ν”„λ₯Ό μ˜λ―Έν•œλ‹€. μ—¬κΈ°μ„œ μœ νš¨ν•˜λ‹€ λΌλŠ” 것은 μ°Έμ‘° ν•  수 μžˆλ‹€λŠ” λœ»μ΄λ‹€.

  int main(void) {
    // block-level scope
    if (1) {
      int x = 5;
      printf("x = %d\n", x);
    }

    //ifλ¬Έ λ‚΄μ—μ„œ μ„ μ–Έλœ λ³€μˆ˜ xλŠ” ifλ¬Έ μ½”λ“œ 블둝 λ‚΄μ—μ„œλ§Œ μœ νš¨ν•˜λ‹€.
    printf("x = %d\n", x); // use of undeclared identifier 'x'

    return 0;
}

  • μžλ°”μŠ€ν¬λ¦½νŠΈλŠ” ν•¨μˆ˜ 레벨 μŠ€μ½”ν”„(function-level-scope)λ₯Ό λ”°λ₯Έλ‹€.
  • ν•¨μˆ˜ 레벨 μŠ€μ½”ν”„λž€, ν•¨μˆ˜ μ½”λ“œ 블둝 λ‚΄μ—μ„œ μ„ μ–Έλœ λ³€μˆ˜λŠ” ν•¨μˆ˜ μ½”λ“œ 블둝 λ‚΄μ—μ„œλ§Œ μœ νš¨ν•˜κ³  ν•¨μˆ˜ μ™ΈλΆ€μ—μ„œλŠ” μœ νš¨ν•˜μ§€ μ•Šλ‹€.
  • 단, ECMAScript6 μ—μ„œ λ„μž…λœ let keywordλŠ” 블둝 레벨 μŠ€μ½”ν”„λ₯Ό μ‚¬μš©ν•  수 μžˆλ‹€.

πŸ‘¨πŸ»β€πŸ’» μ „μ—­ μŠ€μ½”ν”„

  • 전역에 λ³€μˆ˜λ₯Ό μ„ μ–Έν•˜λ©΄ 이 λ³€μˆ˜λŠ” μ–΄λ””μ„œλ“ μ§€ μ°Έμ‘°ν•  수 μžˆλŠ” μ „μ—­ μŠ€μ½”ν”„λ₯Ό κ°–λŠ” μ „μ—­ λ³€μˆ˜κ°€ λœλ‹€.
  • var ν‚€μ›Œλ“œλ‘œ μ„ μ–Έν•œ μ „μ—­ λ³€μˆ˜λŠ” μ „μ—­ 객체(Global Object) window의 ν”„λ‘œνΌν‹° 이닀.
  • μžλ°”μŠ€ν¬λ¦½νŠΈλŠ” λ‹€λ₯Έ C-family languageμ™€λŠ” 달리 νŠΉλ³„ν•œ μ‹œμž‘μ μ΄ μ—†μœΌλ©° μ½”λ“œκ°€ λ‚˜νƒ€λ‚˜λŠ” μ¦‰μ‹œ ν•΄μ„λ˜κ³  μ‹€ν–‰λœλ‹€. λ”°λΌμ„œ 전역에 λ³€μˆ˜λ₯Ό μ„ μ–Έν•˜κΈ° μ‰¬μš°λ©° 이것은 μ „μ—­ λ³€μˆ˜λ₯Ό λ‚¨λ°œν•˜κ²Œ ν•˜λŠ” 문제λ₯Ό μ•ΌκΈ° μ‹œν‚¨λ‹€.
  • μ „μ—­ λ³€μˆ˜μ˜ μ‚¬μš©μ€ λ³€μˆ˜ 이름이 쀑볡될 수 있고, μ˜λ„μΉ˜ μ•Šμ€ μž¬ν• λ‹Ήμ— μ˜ν•œ μƒνƒœ λ³€ν™”λ‘œ μ½”λ“œλ₯Ό μ˜ˆμΈ‘ν•˜κΈ° μ–΄λ ΅κ²Œ λ§Œλ“œλ―€λ‘œ μ‚¬μš©μ„ 지양해야 ν•œλ‹€.

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

πŸ‘¨πŸ»β€πŸ’» ν•¨μˆ˜ 레벨 μŠ€μ½”ν”„

  • μžλ°”μŠ€ν¬λ¦½νŠΈ ECAMScript6 이전에 μ‚¬μš©ν•˜λ˜ var keywordλŠ” ν•¨μˆ˜ μŠ€μ½”ν”„ λ³€μˆ˜λ₯Ό μ„ μ–Έν•  λ•Œ μ‚¬μš©ν•œλ‹€.
  • ν•¨μˆ˜ λ°–μ—μ„œ μ„ μ–Έν•œ ν•¨μˆ˜ μŠ€μ½”ν”„ λ³€μˆ˜λŠ” μ „μ—­ λ²”μœ„λ₯Ό 가지고, ν•¨μˆ˜ μ•ˆμ—μ„œ μ‚¬μš©ν•˜λ©΄ ν•¨μˆ˜ 밖을 μ œμ™Έν•œ λ‚΄λΆ€ μ–΄λ””μ„œλ“  접근이 κ°€λŠ₯ν•œλ‹€.
var a = 'global';

function foo() {
  var b = 'local1';
  console.log(a); //global - μ „μ—­λ³€μˆ˜. 좜λ ₯κ°€λŠ₯.

  if (true) {
    var c = 'local2';
    console.log(b); //local1 - ν•΄λ‹Ή ν•¨μˆ˜ λ‚΄ μ„ μ–Έν•œ λ³€μˆ˜. 좜λ ₯ κ°€λŠ₯.
  }

  console.log(c); //local2 - ν•΄λ‹Ή ν•¨μˆ˜ λ‚΄ μ„ μ–Έν•œ λ³€μˆ˜. 좜λ ₯ κ°€λŠ₯.
}

function bar() {
  var d = 'local3';
  console.log(d); //local3 - ν•΄λ‹Ή ν•¨μˆ˜ λ‚΄ μ„ μ–Έν•œ λ³€μˆ˜. 좜λ ₯ κ°€λŠ₯.
  console.log(a); //global - μ „μ—­λ³€μˆ˜. 좜λ ₯κ°€λŠ₯.
  console.log(b); //ν•΄λ‹Ή ν•¨μˆ˜ λ‚΄ μ„ μ–Έν•œ λ³€μˆ˜κ°€ μ•„λ‹˜. Error
  console.log(c); //ν•΄λ‹Ή ν•¨μˆ˜ λ‚΄ μ„ μ–Έν•œ λ³€μˆ˜κ°€ μ•„λ‹˜. Error
}

foo();
bar();

πŸ‘¨πŸ»β€πŸ’» 블둝 레벨 μŠ€μ½”ν”„

  • 블둝은 0개 μ΄μƒμ˜ ꡬ뢄(statement)을 λ¬ΆκΈ°μœ„ν•΄ μ‚¬μš©ν•˜κ³ , μ€‘κ΄„ν˜Έ { }둜 경계λ₯Ό κ΅¬λΆ„ν•œλ‹€.
  • ECMAScript6λΆ€ν„° λ„μž…λœ let keywordλŠ” 블둝 μŠ€μ½”ν”„ λ³€μˆ˜λ₯Ό μ„ μ–Έν•  λ•Œ μ‚¬μš©ν•œλ‹€.
  • 블둝 μŠ€μ½”ν”„ λ³€μˆ˜λŠ” ν•¨μˆ˜ λ°–μ—μ„œ μ„ μ–Έν•˜λ©΄ ν•¨μˆ˜ μŠ€μ½”ν”„ λ³€μˆ˜μ²˜λŸΌ μ „μ—­ μ ‘κ·Όν•  수 μžˆλ‹€. 블둝 μ•ˆμ—μ„œ μ„ μ–Έν•˜λ©΄ μžμ‹ μ„ μ •μ˜ν•œ 블둝과 ν•˜μœ„ λΈ”λ‘μ—μ„œλ§Œ 접근이 κ°€λŠ₯ν•˜λ‹€.

let foo = "I'm foo";
if (true) {
  let bar = "I'm bar";
  console.log(foo); //I'm foo
  console.log(bar); //I'm bar
}

console.log(foo); //I'm foo
console.log(bar); //Uncaught ReferenceError: bar is not defined.

πŸ‘¨πŸ»β€πŸ’» λ ‰μ‹œμ»¬ μŠ€μ½”ν”„(Lexical Scope)

var x = 1;

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

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

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

  • μœ„ 예제의 μ‹€ν–‰ κ²°κ³ΌλŠ” ν•¨μˆ˜ bar의 μƒμœ„ μŠ€μ½”ν”„κ°€ 무엇인지에 따라 κ²°μ •λœλ‹€. 두가지 νŒ¨ν„΄μ„ μ˜ˆμΈ‘ν•  수 μžˆλ‹€.
  • 첫 번째, ν•¨μˆ˜λ₯Ό μ–΄λ””μ„œ ν˜ΈμΆœν•˜μ˜€λŠ”μ§€μ— 따라 μƒμœ„ μŠ€μ½”ν”„λ₯Ό κ²°μ • -> ν•¨μˆ˜ bar의 μƒμœ„ μŠ€μ½”ν”„λŠ” ν•¨μˆ˜ foo와 μ „μ—­
  • 두 번째, ν•¨μˆ˜λ₯Ό μ–΄λ””μ„œ μ„ μ–Έν•˜μ˜€λŠ”μ§€μ— 따라 μƒμœ„ μŠ€μ½”ν”„λ₯Ό κ²°μ • -> ν•¨μˆ˜ bar의 μƒμœ„ μŠ€μ½”ν”„λŠ” μ „μ—­
  • ν”„λ‘œκ·Έλž˜λ° μ–Έμ–΄λŠ” 이 두가지 방식 쀑 ν•˜λ‚˜μ˜ λ°©μ‹μœΌλ‘œ ν•¨μˆ˜μ˜ μƒμœ„ μŠ€μ½”ν”„λ₯Ό κ²°μ •ν•œλ‹€. 첫번째 방식을 동적 μŠ€μ½”ν”„(Dynamic Scope)라 ν•˜κ³ , 두 번째 방식을 λ ‰μ‹œμ»¬ μŠ€μ½”ν”„(Lexcal Scope)λ˜λŠ” 정적 μŠ€μ½”ν”„(Static Scope)라 ν•œλ‹€.
  • μžλ°”μŠ€ν¬λ¦½νŠΈλ₯Ό λΉ„λ‘―ν•œ λŒ€λΆ€λΆ„μ˜ ν”„λ‘œκ·Έλž˜λ° μ–Έμ–΄λŠ” λ ‰μ‹œμ»¬ μŠ€μ½”ν”„λ₯Ό λ”°λ₯Έλ‹€.
  • μ •λ¦¬ν•˜λ©΄ μœ„ μ˜ˆμ œμ—μ„œ ν•¨μˆ˜ barλŠ” 전역에 μ„ μ–Έλ˜μ–΄μžˆλ‹€. λ”°λΌμ„œ ν•¨μˆ˜ bar의 μƒμœ„ μŠ€μ½”ν”„λŠ” μ „μ—­ μŠ€μ½”ν”„μ΄κ³  μœ„ μ˜ˆμ œλŠ” μ „μ—­ λ³€μˆ˜ x의 κ°’ 1을 λ‘λ²ˆ 좜λ ₯ν•œλ‹€.

μ°Έκ³