Scope

midohreeยท2020๋…„ 7์›” 18์ผ
0
post-thumbnail

Scope ๐Ÿค”?

์šฐ๋ฆฌ๊ฐ€ ์ž‘์„ฑํ•˜๋Š” ์ฝ”๋“œ์˜ ์ ‘๊ทผ ๋ฒ”์œ„๋ฅผ ๊ฒฐ์ •ํ•˜๋Š” ๊ฐœ๋…์ด๋‹ค.

var x = 'global';

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

foo();

console.log(x) // 'global'

์œ„ ์˜ˆ์ œ์—์„œ ์ „์—ญ์— ์„ ์–ธ๋œ ๋ณ€์ˆ˜ x๋Š” ์–ด๋””์—๋“  ์ฐธ์กฐ๊ฐ€ ๊ฐ€๋Šฅํ•˜๋‹ค. ํ•˜์ง€๋งŒ foo ๋‚ด์— ์„ ์–ธ๋œ ๋ณ€์ˆ˜ x๋Š” ํ•จ์ˆ˜ foo ๋‚ด๋ถ€์—์„œ๋งŒ ์ฐธ์กฐํ•  ์ˆ˜ ์žˆ๊ณ , ์™ธ๋ถ€์—์„œ๋Š” ์ฐธ์กฐํ•  ์ˆ˜ ์—†๋‹ค. ์ด๋Ÿฌํ•œ ๊ทœ์น™์„ ์Šค์ฝ”ํ”„๋ผ๊ณ  ํ•œ๋‹ค.

var x = 'global';

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

foo();

console.log(x) // 'function scope'

ํ•จ์ˆ˜์ง€์—ญ์—์„œ ์ „์—ญ๋ณ€์ˆ˜๋ฅผ ์ฐธ์กฐ ํ•  ์ˆ˜ ์žˆ์œผ๋ฏ€๋กœ, ์ง€์—ญ๋ณ€์ˆ˜์˜ ๊ฐ’์ด ๋ณ€๊ฒฝ๋˜๋ฉด ์ „์—ญ๋ณ€์ˆ˜์˜ ๊ฐ’๋„ ๋ณ€๊ฒฝ๋œ๋‹ค. ๋‚ด๋ถ€ํ•จ์ˆ˜์˜ ๊ฒฝ์šฐ ์ „์—ญ๋ณ€์ˆ˜๋Š” ๋ฌผ๋ก  ์ƒ์œ„ ํ•จ์ˆ˜์—์„œ ์„ ์–ธํ•œ ๋ณ€์ˆ˜์— ์ ‘๊ทผ/๋ณ€๊ฒฝ์ด ๊ฐ€๋Šฅํ•˜๋‹ค.


์Šค์ฝ”ํ”„์˜ ๊ตฌ๋ถ„

์ „์—ญ์Šค์ฝ”ํ”„ (Global scope)

: ์ฝ”๋“œ ์–ด๋””์—์„œ๋“  ์ฐธ์กฐํ•  ์ˆ˜ ์žˆ๋‹ค. => ์ „์—ญ๋ณ€์ˆ˜
: var๋กœ ์„ ์–ธํ•œ ์ „์—ญ๋ณ€์ˆ˜๋Š” ์ „์—ญ๊ฐ์ฒด window์˜ ํ”„๋กœํผํ‹ฐ์ด๋‹ค.

var global = 'global';

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

foo();

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

์ง€์—ญ์Šค์ฝ”ํ”„ (Local scope or Function-level scope)

: ์ฝ”๋“œ ๋ธ”๋ก์ด ๋งŒ๋“  ์Šค์ฝ”ํ”„. ํ•จ์ˆ˜ ์ž์‹ ๊ณผ ํ•˜์œ„ ํ•จ์ˆ˜์—๋งŒ ์ฐธ์กฐํ•  ์ˆ˜ ์žˆ๋‹ค. => ์ง€์—ญ๋ณ€์ˆ˜


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

  • ํ•จ์ˆ˜ ๋ ˆ๋ฒจ ์Šค์ฝ”ํ”„(function-level scope)๋ฅผ ๋”ฐ๋ฅธ๋‹ค.
  • ํ•จ์ˆ˜ ๋ ˆ๋ฒจ ์Šค์ฝ”ํ”„๋Š” ํ•จ์ˆ˜ ์ฝ”๋“œ ๋ธ”๋ก ๋‚ด์—์„œ ์„ ์–ธ๋œ ๋ณ€์ˆ˜๋Š” ํ•จ์ˆ˜ ์ฝ”๋“œ๋ธ”๋ก ๋‚ด์—์„œ๋งŒ ์œ ํšจํ•˜๊ณ  ์™ธ๋ถ€์—์„œ๋Š” ์œ ํšจํ•˜์ง€ ์•Š๋Š”๋‹ค.
if(true) {
  var x = 5;
}

console.log(x); // 5

// ๋ณ€์ˆ˜ x๋Š” ์ฝ”๋“œ๋ธ”๋ก ๋‚ด์—์„œ ์„ ์–ธ๋˜์—ˆ๋‹ค. 
// ํ•˜์ง€๋งŒ javascript๋Š” ํ•จ์ˆ˜ ๋ ˆ๋ฒจ ์Šค์ฝ”ํ”„์ด๊ธฐ ๋•Œ๋ฌธ์—, 
// ์ฝ”๋“œ๋ธ”๋ก ๋‚ด์— ์„ ์–ธ๋˜์—ˆ๋‹ค ํ• ์ง€๋ผ๋„ 
// ๋ชจ๋‘ ์ „์—ญ์Šค์ฝ”ํ”„๋ฅผ ๊ฐ–๊ฒŒ ๋œ๋‹ค. 
// ๋ณ€์ˆ˜ x๋Š” ์ „์—ญ๋ณ€์ˆ˜์ด๋‹ค. 
var a = 10; // ์ „์—ญ๋ณ€์ˆ˜

(function () {
  var b = 20; // ์ง€์—ญ๋ณ€์ˆ˜
})();

console.log(a); // 10
console.log(b); // Error: 'b' is not defined
var x = 'global';

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

foo();

console.log(x) // global
  • ๋‹จ, let ์„ ์‚ฌ์šฉํ•˜๋ฉด ๋ธ”๋ก ๋ ˆ๋ฒจ ์Šค์ฝ”ํ”„(Block-level scope) ๋ฅผ ์‚ฌ์šฉ ํ•  ์ˆ˜ ์žˆ๋‹ค. ๋ธ”๋ก ๋ ˆ๋ฒจ ์Šค์ฝ”ํ”„๋Š” ๋ง ๊ทธ๋Œ€๋กœ ๋ธ”๋ก {} ์ด ์ƒ์„ฑ๋  ๋•Œ ๋งˆ๋‹ค ์ƒˆ๋กœ์šด ์Šค์ฝ”ํ”„๊ฐ€ ํ˜•์„ฑ๋˜๋Š” ๊ฒƒ์„ ์˜๋ฏธํ•œ๋‹ค. let๊ณผ const์˜ ๋“ฑ์žฅ์œผ๋กœ ๋ธ”๋ก์Šค์ฝ”ํ”„๋ฅผ ํ˜•์„ฑํ•˜๋Š” ๊ฒƒ๋„ ๊ฐ€๋Šฅํ•ด์กŒ๋‹ค.

  • ํƒ€ ์–ธ์–ด๋“ค์€ ๋ชจ๋‘ ๋ธ”๋ก ๋ ˆ๋ฒจ ์Šค์ฝ”ํ”„๋ฅผ ๋”ฐ๋ฅธ๋‹ค. ์ด๋Š” ์ฝ”๋“œ ๋ธ”๋ก ๋‚ด์—์„œ ์œ ํšจํ•œ(์ฐธ์กฐ ๊ฐ€๋Šฅํ•œ) ์Šค์ฝ”ํ”„์ด๋‹ค.

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

for๋ฌธ์—์„œ์˜ var๊ณผ let

function loop () {
  for (var i = 0; i < 5; i++) {
    console.log(i);
  }
  console.log(i, "final");
}

loop();

/*
0
1
2
3
4
5 final
*/

-> var๋Š” ํ•จ์ˆ˜๋ ˆ๋ฒจ์Šค์ฝ”ํ”„๋ฅผ ๋”ฐ๋ฅด๊ธฐ ๋•Œ๋ฌธ์—, loop ํ•จ์ˆ˜ ์ŠคํฌํŠธ ์•ˆ์— i๊ฐ€ ๋ชจ๋‘ ์กด์žฌํ•œ๋‹ค.

function loop () {
  for (let i = 0; i < 5; i++) {
    console.log(i);
  }
  
  console.log(i, "final");
}

loop();

// Error: i is not defined

-> let์œผ๋กœ ๋ธ”๋ก๋ ˆ๋ฒจ์Šค์ฝ”ํ”„๊ฐ€ ๊ฐ€๋Šฅํ•ด์กŒ๊ธฐ ๋•Œ๋ฌธ์— i๋Š” for๋ฌธ ์ฝ”๋“œ๋ธ”๋ก ์•ˆ์—๋งŒ ์กด์žฌํ•œ๋‹ค.


๋ ‰์‹œ์ปฌ ์Šค์ฝ”ํ”„

var x = 1;

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

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

foo();
bar();
  

๋™์  ์Šค์ฝ”ํ”„(Dynamic scope)

  • ํ•จ์ˆ˜๋ฅผ ์–ด๋””์„œ ํ˜ธ์ถœํ•˜์˜€๋Š”์ง€์— ๋”ฐ๋ผ ์ƒ์œ„ ์Šค์ฝ”ํ”„๋ฅผ ๊ฒฐ์ •ํ•œ๋‹ค.

์ •์  ์Šค์ฝ”ํ”„(Lexical scope)

  • ํ•จ์ˆ˜๋ฅผ ์–ด๋””์„œ ํ˜ธ์ถœํ•˜๋Š”์ง€๊ฐ€ ์•„๋‹Œ, โญ๏ธ์–ด๋””์—โญ๏ธ ์„ ์–ธํ•˜์˜€๋Š”์ง€์— ๋”ฐ๋ผ ๊ฒฐ์ •๋œ๋‹ค.
  • ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๋ฅผ ๋น„๋กฏํ•œ ๋Œ€๋ถ€๋ถ„์˜ ์–ธ์–ด๋Š” ๋ ‰์‹œ์ปฌ ์Šค์ฝ”ํ”„๋ฅผ ๋”ฐ๋ฅธ๋‹ค.
  • ํ•จ์ˆ˜๋ฅผ ์„ ์–ธํ•œ ์‹œ์ ์— ์ƒ์œ„ ์Šค์ฝ”ํ”„๊ฐ€ ๊ฒฐ์ •๋œ๋‹ค.
  • ํ•จ์ˆ˜ bar๋Š” ์ „์—ญ์— ์„ ์–ธ๋˜์—ˆ๋‹ค. ๊ทธ๋Ÿฌ๋ฏ€๋กœ bar์˜ ์ƒ์œ„ ์Šค์ฝ”ํ”„๋Š” ์ „์—ญ์Šค์ฝ”ํ”„์ด๊ณ , 1์„ ๋‘๋ฒˆ ์ถœ๋ ฅํ•œ๋‹ค.

Scope chain ๐Ÿงฌ

์ƒ์œ„ Global Scope -> Person Scope -> displayName Scope ํ•˜์œ„

โญ๏ธ

Scope ๊ณ„์ธต์—์„œ ๊ฐ€์žฅ ์ค‘์š”ํ•œ ํŠน์ง•์€

  1. ์ƒ์œ„์—์„œ ํ•˜์œ„ ๋‚ด๋ถ€์ •๋ณด๋ฅผ ์ ‘๊ทผ ํ•  ์ˆ˜ ์—†๋‹ค.
  2. ํ•˜์ง€๋งŒ ํ•˜์œ„์—์„œ ์ƒ์œ„ scope์˜ ์ •๋ณด๋Š” ์ ‘๊ทผ ๊ฐ€๋Šฅํ•˜๋‹ค !!
  3. ๊ทธ๋ฆฌ๊ณ , ์‹คํ–‰๋ฌธ์˜ ์œ„์น˜๋ฅผ ๊ธฐ์ค€์œผ๋กœ ํ•˜์œ„ Scope ๋ถ€ํ„ฐ ์‹œ์ž‘ํ•˜์—ฌ, ์›ํ•˜๋Š” ๊ฐ’์„ ์ฐพ์„ ๋•Œ ๊นŒ์ง€ ์ƒ์œ„๋กœ ํƒ์ƒ‰์ด ๊ฐ€๋Šฅํ•˜๋‹ค.

์•”๋ฌต์  ์ „์—ญ ๐Ÿคซ

var x = 10;

function foo () {
  y = 20;
  console.log(x + y);
}

foo(); // 30

y๋ฅผ ์„ ์–ธํ•ด์ฃผ์ง€ ์•Š์•˜๋Š”๋ฐ ์™œ 30์ด๋ผ๋Š” ๊ฐ’์ด ๋‚˜์˜ฌ๊นŒ?

fooํ•จ์ˆ˜์˜ ์Šค์ฝ”ํ”„์™€ ์ „์—ญ ์Šค์ฝ”ํ”„ ์–ด๋””์—์„œ๋„ ๋ณ€์ˆ˜ y์˜ ์„ ์–ธ์„ ์ฐพ์„ ์ˆ˜ ์—†์œผ๋ฏ€๋กœ ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•ด์•ผ ํ•˜์ง€๋งŒ, ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ์—”์ง„์€ y = 20 ์„ window.y = 20 ์œผ๋กœ ํ•ด์„ํ•˜์—ฌ ํ”„๋กœํผํ‹ฐ๋ฅผ ๋™์  ์ƒ์„ฑํ•œ๋‹ค. ๊ฒฐ๊ตญ y๋Š” ์ „์—ญ ๊ฐ์ฒด์˜ ํ”„๋กœํผํ‹ฐ๊ฐ€ ๋˜์–ด ์ „์—ญ๋ณ€์ˆ˜์ฒ˜๋Ÿผ ๋™์ž‘ํ•˜๋Š”๋ฐ ์ด๋Ÿฌํ•œ ํ˜„์ƒ์„ ์•”๋ฌต์  ์ „์—ญ(implicit global) ์ด๋ผ๊ณ  ํ•œ๋‹ค.

console.log(x); // undefined - ์ „์—ญ ๋ณ€์ˆ˜ x๋Š” ํ˜ธ์ด์ŠคํŒ… ๋ฐœ์ƒํ•œ๋‹ค. 
console.log(y); // Error : y is not defined - ์ „์—ญ๋ณ€์ˆ˜๊ฐ€ ์•„๋‹Œ, ๋‹จ์ง€ ์ „์—ญ ํ”„๋กœํผํ‹ฐ์ธ y๋Š” ํ˜ธ์ด์ŠคํŒ…์ด ๋ฐœ์ƒํ•˜์ง€ ์•Š๋Š”๋‹ค. 

var x = 10; // ์ „์—ญ ๋ณ€์ˆ˜

function foo () {
  y = 20; // ์„ ์–ธํ•˜์ง€ ์•Š์€ ๋ณ€์ˆ˜
  console.log(x + y);
}

foo(); // 30

์ „์—ญ๋ณ€์ˆ˜.. ์‚ฌ์šฉํ• ๊นŒ ๋ง๊นŒ??

1) ์ตœ์†Œํ•œ์˜ ์ „์—ญ๋ณ€์ˆ˜ ์‚ฌ์šฉ

  • ์ „์—ญ๋ณ€์ˆ˜ ๊ฐ์ฒด ํ•˜๋‚˜๋ฅผ ๋งŒ๋“ค์–ด์„œ ์‚ฌ์šฉํ•ด ์ „์—ญ๋ณ€์ˆ˜ ์‚ฌ์šฉ์„ ์ตœ์†Œํ™”์‹œํ‚จ๋‹ค.
var globalObj = {};

globalObj.person = {
  name: 'Midohree',
  gender: 'female'
};

console.log(globalObj.person.name);

2) ์ฆ‰์‹œ์‹คํ–‰ํ•จ์ˆ˜๋ฅผ ์ด์šฉํ•œ ์ „์—ญ๋ณ€์ˆ˜ ์‚ฌ์šฉ ์–ต์ œ.

  • ์ฆ‰์‹œ์‹คํ–‰ํ•จ์ˆ˜(IIFE : Immediately Invoked Function Expression) ๋Š” ์ฆ‰์‹œ ์‹คํ–‰๋˜๊ณ , ๊ทธ ํ›„ ์ „์—ญ์—์„œ ๋ฐ”๋กœ ์‚ฌ๋ผ์ง„๋‹ค.
(function () {
  var globalObj = {};

  globalObj.person = {
    name: 'Midohree',
    gender: 'female'
  };

  console.log(globalObj.person.name); // Midohree
}());

console.log(globalObj.person.name); // Error: globalObj is not defined
profile
๐Ÿ’ป

0๊ฐœ์˜ ๋Œ“๊ธ€