๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ
Programming/4. JavaScript & React

008_์Šค์ฝ”ํ”„(Scope) ๐Ÿ”ญ

by @sangseophwang 2022. 2. 23.

 

๐Ÿ”ญ  ์Šค์ฝ”ํ”„๋ž€?

  • ๋‹จ์–ด ์ž์ฒด์˜ ์‚ฌ์ „์  ์˜๋ฏธ๋กœ๋Š” '๋ฒ”์œ„' ๋ผ๋Š” ๋œป์„ ๊ฐ€์ง„๋‹ค.
  • CS, ๊ทธ๋ฆฌ๊ณ  JavaScript์—์„œ๋„ '๋ฒ”์œ„' ๋ผ๋Š” ์˜๋ฏธ๋ฅผ ๊ฐ–๋Š”๋‹ค. 
  • ์ข€ ๋” ๊ตฌ์ฒด์ ์ธ ๋œป์€ '์ฐธ์กฐ ๋Œ€์ƒ ์‹๋ณ„์ž( identifier, ๋ณ€์ˆ˜, ํ•จ์ˆ˜์˜ ์ด๋ฆ„๊ณผ ๊ฐ™์ด ์–ด๋–ค ๋Œ€์ƒ์„ ๋‹ค๋ฅธ ๋Œ€์ƒ๊ณผ ๊ตฌ๋ถ„ํ•ด ์‹๋ณ„ํ•  ์ˆ˜ ์žˆ๋Š” ์œ ์ผํ•œ ์ด๋ฆ„ )๋ฅผ ์ฐพ์•„๋‚ด๊ธฐ ์œ„ํ•œ ๊ทœ์น™' ์„ ๋œปํ•œ๋‹ค.
// ์˜ˆ์‹œ ์ฝ”๋“œ

const x = 'global';

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

foo(); // ?
console.log(x); // ?
  • ์œ„ ์˜ˆ์ œ์—์„œ ๋ณด๋ฉด ๋ณ€์ˆ˜ x๊ฐ€ ์ค‘๋ณต ์„ ์–ธ๋๋Š”๋ฐ, ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๋Š” ์Šค์ฝ”ํ”„๋ฅผ ํ†ตํ•ด ์ „์—ญ์— ์„ ์–ธ๋œ ๋ณ€์ˆ˜ x์™€ ํ•จ์ˆ˜ foo ๋‚ด๋ถ€์˜ ๋ณ€์ˆ˜ x๋ฅผ ๊ตฌ๋ถ„ํ•  ์ˆ˜ ์žˆ๋‹ค.
  • ์Šค์ฝ”ํ”„๋ฅผ ๊ตฌ๋ถ„ํ•ด๋ณด์ž๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™์ด 2๊ฐ€์ง€๋กœ ๋‚˜๋ˆŒ ์ˆ˜ ์žˆ๋‹ค.
์ „์—ญ ์Šค์ฝ”ํ”„ (Global Scope)
์ฝ”๋“œ ์–ด๋””์—์„œ๋“ ์ง€ ์ฐธ์กฐํ•  ์ˆ˜ ์žˆ๋‹ค.

์ง€์—ญ ์Šค์ฝ”ํ”„ (Local Scope or Funtion-level Scope)
ํ•จ์ˆ˜ ์ฝ”๋“œ ๋ธ”๋ก์ด ๋งŒ๋“  ์Šค์ฝ”ํ”„๋กœ ํ•จ์ˆ˜ ์ž์‹ ๊ณผ ํ•˜์œ„ ํ•จ์ˆ˜์—์„œ๋งŒ ์ฐธ์กฐํ•  ์ˆ˜ ์žˆ๋‹ค.
  • ๋ชจ๋“  ๋ณ€์ˆ˜๋Š” ์Šค์ฝ”ํ”„๋ฅผ ๊ฐ–๋Š”๋‹ค. ๋ณ€์ˆ˜์˜ ๊ด€์ ์—์„œ ์Šค์ฝ”ํ”„๋ฅผ ๊ตฌ๋ถ„ํ•˜๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™์ด ๋‚˜๋ˆŒ ์ˆ˜ ์žˆ๋‹ค.
์ „์—ญ ๋ณ€์ˆ˜ (Global variable)
์ „์—ญ์—์„œ ์„ ์–ธ๋œ ๋ณ€์ˆ˜์ด๋ฉฐ ์–ด๋””์—๋“  ์ฐธ์กฐํ•  ์ˆ˜ ์žˆ๋‹ค.

์ง€์—ญ ๋ณ€์ˆ˜ (Local variable)
์ง€์—ญ(ํ•จ์ˆ˜) ๋‚ด์—์„œ ์„ ์–ธ๋œ ๋ณ€์ˆ˜์ด๋ฉฐ ๊ทธ ์ง€์—ญ๊ณผ ๊ทธ ์ง€์—ญ์˜ ํ•˜๋ถ€ ์ง€์—ญ์—์„œ๋งŒ ์ฐธ์กฐํ•  ์ˆ˜ ์žˆ๋‹ค.

 

๐Ÿ’ก ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ์Šค์ฝ”ํ”„์˜ ํŠน์ง•

  • ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ์Šค์ฝ”ํ”„๋Š” ํƒ€ ์–ธ์–ด์™€๋Š” ๋‹ค๋ฅธ ํŠน์ง•์„ ๊ฐ€์ง€๊ณ  ์žˆ๋‹ค.
  • ๋Œ€๋ถ€๋ถ„์˜ C ๊ณ„์—ด ์–ธ์–ด๋Š” ๋ธ”๋ก ๋ ˆ๋ฒจ ์Šค์ฝ”ํ”„(block-level scope)๋ฅผ ๋”ฐ๋ฅธ๋‹ค. ๋ธ”๋ก ๋ ˆ๋ฒจ ์Šค์ฝ”ํ”„๋ž€ ์ฝ”๋“œ ๋ธ”๋ก({...}) ๋‚ด์—์„œ ์œ ํšจํ•œ ์Šค์ฝ”ํ”„๋ฅผ ์˜๋ฏธํ•œ๋‹ค. ์—ฌ๊ธฐ์„œ '์œ ํšจํ•˜๋‹ค'๋Š” '์ฐธ์กฐ(์ ‘๊ทผ)ํ•  ์ˆ˜ ์žˆ๋‹ค' ๋Š” ๋œป์ด๋‹ค.
int main(void) {
  // block level scope
  if (1) {
	int x = 5;
	printf("x = %d\n", x);
  }
  printf("x = %d\n", x); // use of undeclared identifier 'x'

  return 0;
}
  • ์œ„ C์–ธ์–ด ์ฝ”๋“œ๋ฅผ ๋ณด๋ฉด if๋ฌธ ๋‚ด์— ์„ ์–ธ๋œ ๋ณ€์ˆ˜ x๋Š” if๋ฌธ ์ฝ”๋“œ ๋ธ”๋ก ๋‚ด์—์„œ๋งŒ ์œ ํšจํ•˜๋‹ค. ์ฆ‰, if๋ฌธ ๋ฐ”๊นฅ์—์„œ๋Š” ์ฐธ์กฐ๊ฐ€ ๋ถˆ๊ฐ€๋Šฅํ•˜๋‹ค.
  • ํ•˜์ง€๋งŒ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๋Š” ํ•จ์ˆ˜ ๋ ˆ๋ฒจ ์Šค์ฝ”ํ”„(function-level scope)๋ฅผ ๋”ฐ๋ฅธ๋‹ค. ์ฆ‰ ํ•จ์ˆ˜ ๋‚ด์—์„œ ์„ ์–ธ๋œ ๋ณ€์ˆ˜๋Š” ํ•จ์ˆ˜ ๋‚ด์—์„œ ์œ ํšจํ•˜๋‹ค๋Š” ๋œป์ด๋‹ค.
  • ๋‹จ, ES6์—์„œ ๋„์ž…๋œ let์„ ์‚ฌ์šฉํ•˜๋ฉด ๋ธ”๋ก ๋ ˆ๋ฒจ ์Šค์ฝ”ํ”„๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.

์—์‹œ 1

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

 

์—์‹œ 2

// var์€ ๋น„ ๋ธ”๋ก ๋ ˆ๋ฒจ ์Šค์ฝ”ํ”„์ด๋‹ค.
if (true) {
  var x = 5;
}
console.log(x);  // 5


// let์€ ๋ธ”๋ก ๋ ˆ๋ฒจ ์Šค์ฝ”ํ”„์ด๋‹ค.
if (true) {
  let x = 5;
}
console.log(x); // ReferenceError: x is not defined

 

์˜ˆ์‹œ 3

// ํ•จ์ˆ˜(์ง€์—ญ) ์˜์—ญ์—์„œ ์ „์—ญ๋ณ€์ˆ˜๋ฅผ ์ฐธ์กฐํ•  ์ˆ˜ ์žˆ์œผ๋ฏ€๋กœ ์ „์—ญ ๋ณ€์ˆ˜์˜ ๊ฐ’๋„ ๋ณ€๊ฒฝํ•  ์ˆ˜ ์žˆ๋‹ค.

var x = 10;

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

 

๐Ÿ”” ์Šค์ฝ”ํ”„์˜ ์ฃผ์š” ๊ทœ์น™

  • ์•ˆ์ชฝ ์Šค์ฝ”ํ”„์—์„œ ๋ฐ”๊นฅ์ชฝ ์Šค์ฝ”ํ”„๋กœ ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ์ง€๋งŒ ๋ฐ˜๋Œ€๋Š” ๋ถˆ๊ฐ€๋Šฅํ•˜๋‹ค.
  • ์ง€์—ญ ๋ณ€์ˆ˜๋Š” ์ „์—ญ ๋ณ€์ˆ˜๋ณด๋‹ค ์šฐ์„ ์ˆœ์œ„๊ฐ€ ๋” ๋†’๋‹ค.
  • ์Šค์ฝ”ํ”„๋Š” ์ค‘์ฒฉ์ด ๊ฐ€๋Šฅํ•˜๋‹ค.

 

์ง€์—ญ ๋ณ€์ˆ˜ ์šฐ์„ ์ˆœ์œ„ ์˜ˆ

var x = 'global';

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

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

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

 

์ค‘์ฒฉ ์Šค์ฝ”ํ”„ ์˜ˆ

var x = 10;

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

  function bar(){
    x = 1000;
    console.log(x); // 1000
  }

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

// ์ค‘์ฒฉ ์Šค์ฝ”ํ”„๋Š” ๊ฐ€์žฅ ์ธ์ ‘ํ•œ ์ง€์—ญ์„ ์šฐ์„ ํ•ด ์ฐธ์กฐํ•œ๋‹ค.

 

๐Ÿ›  ์Šค์ฝ”ํ”„์™€ var, let, const

  • ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ๋ณ€์ˆ˜ ์„ ์–ธ ํ‚ค์›Œ๋“œ ์„ธ๊ฐ€์ง€์˜ ์ฐจ์ด์  ๋ฐ ์Šค์ฝ”ํ”„ ์œ ํšจ ๋ฒ”์œ„๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค.
  const let var
์œ ํšจ ๋ฒ”์œ„ ๋ธ”๋ก ์Šค์ฝ”ํ”„ / ํ•จ์ˆ˜ ์Šค์ฝ”ํ”„ ๋ธ”๋ก ์Šค์ฝ”ํ”„ / ํ•จ์ˆ˜ ์Šค์ฝ”ํ”„ ํ•จ์ˆ˜ ์Šค์ฝ”ํ”„
๊ฐ’ ์žฌํ• ๋‹น ๋ถˆ๊ฐ€๋Šฅ ๊ฐ€๋Šฅ ๊ฐ€๋Šฅ
์žฌ์„ ์–ธ ๋ถˆ๊ฐ€๋Šฅ ๋ถˆ๊ฐ€๋Šฅ ๊ฐ€๋Šฅ
์ „์—ญ ์Šค์ฝ”ํ”„ x x o
  • ์—ฌ๊ธฐ์„œ ์ฃผ๋ชฉํ•ด์•ผํ•  ์ ์€ var์˜ ์œ ํšจ ๋ฒ”์œ„์™€ ์ „์—ญ ์Šค์ฝ”ํ”„ ์—ฌ๋ถ€์ธ๋ฐ ๊ทธ ์˜ˆ์‹œ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค.
for (var i = 0; i < 10; i++) {
  console.log(i);
}

console.log(i); // 9

// for๋ฌธ์—์„œ ์„ ์–ธ๋œ i ๋ณ€์ˆ˜์ง€๋งŒ ๋ชจ๋“  ์Šค์ฝ”ํ”„์—์„œ ์ ‘๊ทผ ๊ฐ€๋Šฅํ•˜๋‹ค.

 

๐Ÿšท ์Šค์ฝ”ํ”„ ๊ด€๋ จ ๋ณ€์ˆ˜ ์„ ์–ธ์‹œ ์ฃผ์˜์ 

 

โœ๏ธ  ์ „์—ญ ๊ฐ์ฒด(window)์˜ ์ดํ•ด

  • Window ๊ฐ์ฒด๋Š” ๋ธŒ๋ผ์šฐ์ €์—์„œ๋งŒ ์กด์žฌํ•˜๋Š” ๊ฐ์ฒด๋‹ค.
  • ๋ธŒ๋ผ์šฐ์ €์˜ ์ฐฝ(window)์„ ์˜๋ฏธํ•˜๋Š” ๊ฐ์ฒด์ด๋‹ค.
  • ํ•˜์ง€๋งŒ ๋ณ„๊ฐœ๋กœ ์ „์—ญ ์˜์—ญ์„ ๋‹ด๊ณ  ์žˆ๊ธฐ๋„ ํ•˜๋‹ค. ๊ทธ๋ž˜์„œ ํ•จ์ˆ˜ ์„ ์–ธ์‹์œผ๋กœ ํ•จ์ˆ˜๋ฅผ ์„ ์–ธํ•˜๊ฑฐ๋‚˜, var ํ‚ค์›Œ๋“œ๋กœ ๋ณ€์ˆ˜๋ฅผ ์„ ์–ธํ•˜๋ฉด window ๊ฐ์ฒด์— ์†ํ•ด์ง„๋‹ค.

โœ๏ธ  ์ „์—ญ ๋ณ€์ˆ˜๋Š” ์ตœ์†Œํ™”ํ•˜์ž

  • ์ „์—ญ ๋ณ€์ˆ˜๋Š” ์–ด๋””์„œ๋“  ์ ‘๊ทผ์ด ๊ฐ€๋Šฅํ•˜๋‹ค๋Š” ํŠน์ง•์ด ์žˆ๋‹ค.
  • ์ „์—ญ ๋ณ€์ˆ˜๋ฅผ ์ตœ์†Œํ™”ํ•ด์•ผ side effect(์˜๋„ํ•˜์ง€ ์•Š์€ ๋กœ์ง์— ์˜ํ•œ ๋ฌธ์ œ ๋ฐœ์ƒ)๋ฅผ ์ค„์ผ ์ˆ˜ ์žˆ๋‹ค.

โœ๏ธ  ์„ ์–ธ ์—†๋Š” ๋ณ€์ˆ˜ ํ• ๋‹น ๊ธˆ์ง€

  • let, const ๋“ฑ์œผ๋กœ ์„ ์–ธํ•˜์ง€ ์•Š๊ณ  ๋ณ€์ˆ˜๋ฅผ ํ• ๋‹นํ•˜๋ฉด ํ•ด๋‹น ๋ณ€์ˆ˜๋Š” var๋กœ ์„ ์–ธํ•œ ์ „์—ญ ๋ณ€์ˆ˜ ์ทจ๊ธ‰์„ ํ•œ๋‹ค.
  • ์‹ค์ˆ˜๋ฅผ ๋ฐฉ์ง€ํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” Strict Mode๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๋œ๋‹ค.
    • Strict Mode๋Š” ๋ธŒ๋ผ์šฐ์ €๊ฐ€ ๋ณด๋‹ค ์—„๊ฒฉํ•˜๊ฒŒ ์ž‘๋™ํ•˜๋„๋ก ๋งŒ๋“ค์–ด์ค€๋‹ค.
    • ๊ทธ๋ž˜์„œ ์„ ์–ธ ์—†๋Š” ๋ณ€์ˆ˜ ํ• ๋‹น์˜ ๊ฒฝ์šฐ๋„ ์—๋Ÿฌ๋กœ ํŒ๋‹จํ•ด์ค€๋‹ค.
    • ๋ณดํ†ต ๋ฆฌ์•กํŠธ๋Š” index ํŒŒ์ผ์— Strict Mode๊ฐ€ ์ ์šฉ๋ผ์žˆ์ง€๋งŒ, ๊ทธ๋ƒฅ JS๋กœ ํ”„๋กœ์ ํŠธ๋ฅผ ๋งŒ๋“œ๋ ค๋ฉด js ํŒŒ์ผ ์ƒ๋‹จ์— 'use strict'๋ฅผ ์ž…๋ ฅํ•ด์ฃผ๋ฉด ๋œ๋‹ค.
๋ฐ˜์‘ํ˜•

๋Œ“๊ธ€