Frontend/JavaScript

[JavaScript] ํด๋กœ์ €๋ž€ ๋ฌด์—‡์ธ๊ฐ€?

_์„ฑํ˜ธ_ 2022. 9. 2. 12:27
728x90
๋ฐ˜์‘ํ˜•

ํด๋กœ์ € โ“

ํ•จ์ˆ˜์™€ ํ•จ์ˆ˜๊ฐ€ ์„ ์–ธ๋œ ์–ดํœ˜์  ํ™˜๊ฒฝ์˜ ์กฐํ•ฉ

์ด ํ™˜๊ฒฝ์€ ํด๋กœ์ €๊ฐ€ ์ƒ์„ฑ๋œ ์‹œ์ ์˜ ์œ ํšจ ๋ฒ”์œ„ ๋‚ด์— ์žˆ๋Š” ๋ชจ๋“  ์ง€์—ญ ๋ณ€์ˆ˜๋กœ ๊ตฌ์„ฑ๋œ๋‹ค.

์ฆ‰, ๋‚ด๋ถ€ ํ•จ์ˆ˜์—์„œ ์™ธ๋ถ€ ํ•จ์ˆ˜์— ์žˆ๋Š” ์ƒํƒœ์— ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๋Š” ๊ถŒํ•œ์„ ๋ถ€์—ฌํ•œ๋‹ค๋Š” ๊ฒƒ์ด๋‹ค.

 

์™œ ์‚ฌ์šฉํ• ๊นŒ โ“

๋‚ด๋ถ€ ์ •๋ณด๋ฅผ ์€๋‹‰ํ•˜๊ณ , ๊ณต๊ฐœ ํ•จ์ˆ˜(public ๋˜๋Š” ์™ธ๋ถ€)๋ฅผ ํ†ตํ•œ ๋ฐ์ดํ„ฐ ์กฐ์ž‘์„ ์œ„ํ•ด ์‚ฌ์šฉํ•œ๋‹ค. (์บก์Šํ™”, ์ •๋ณด์€๋‹‰)

์ „์—ญ๋ณ€์ˆ˜ ๋˜ํ•œ ์ค„์—ฌ์ง€๊ฒŒ ๋˜๋ฏ€๋กœ ๊ฐœ๋ฐœ ๊ณผ์ •์—์„œ ์‹ค์ˆ˜๋กœ ์ ‘๊ทผํ•˜๋Š” ์ผ์ด ์•ˆ์ƒ๊ธด๋‹ค. 

ํ˜„์žฌ๋Š” ํด๋ž˜์Šค์—์„œ์˜ private ํ•„๋“œ ๋˜๋Š” ๋ฉ”์†Œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๋œ๋‹ค.

 

์–ด๋–ป๊ฒŒ ์ด๊ฒƒ์ด ๊ฐ€๋Šฅํ• ๊นŒ โ“

 inner ๋ ‰์‹œ์ปฌ ํ™˜๊ฒฝ์ด ์™ธ๋ถ€ ๋ ‰์‹œ์ปฌ ํ™˜๊ฒฝ์„ ์ฐธ์กฐํ•˜๊ณ  ์žˆ๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.

ํด๋กœ์ €๋ฅผ ์ž˜ ์ดํ•ดํ•˜๋ ค๋ฉด ์–ด๋–ป๊ฒŒ ๋ณ€์ˆ˜์˜ ์œ ํšจ๋ฒ”์œ„๋ฅผ ์ง€์ •ํ•˜๋Š”์ง€(Lexical scoping)๋ฅผ ๋จผ์ € ์ดํ•ดํ•ด์•ผ ํ•œ๋‹ค.

๐Ÿ“Œ์ฐธ๊ณ 

์‹คํ–‰ ์ปจํ…์ŠคํŠธ

  • ์‹๋ณ„์ž๊ฐ€ ์„ ์–ธ๋˜๋Š” ํ™˜๊ฒฝ์œผ๋กœ, ์ฝ”๋“œ์˜ ์‹คํ–‰์ˆœ์„œ์™€ ์Šค์ฝ”ํ”„๋ฅผ ๊ธฐ์–ต
  • ์Šค์ฝ”ํ”„๋ฅผ ๊ตฌ๋ถ„ํ•˜์—ฌ ์‹๋ณ„์ž๋ฅผ ๋“ฑ๋กํ•˜๊ณ  ๊ด€๋ฆฌํ•˜๋Š” ์ €์žฅ์†Œ ์—ญํ• 

๋ ‰์‹œ์ปฌ ํ™˜๊ฒฝ์€ 3๊ฐ€์ง€์˜ ์ปดํฌ๋„ŒํŠธ๋กœ ๊ตฌ์„ฑ

  • ํ™˜๊ฒฝ ๋ ˆ์ฝ”๋“œ(Environment Record)
  • ์™ธ๋ถ€ ๋ ‰์‹œ์ปฌ ํ™˜๊ฒฝ ์ฐธ์กฐ(Outer Lexical Environment Reference)
  •  this ๋ฐ”์ธ๋”ฉ(This binding)

 

๐Ÿ“ ์–ดํœ˜์  ๋ฒ”์œ„ ์ง€์ •(Lexical scoping)

function init() {
  var name = 'SeongHo'; // name์€ init์— ์˜ํ•ด ์ƒ์„ฑ๋œ ์ง€์—ญ ๋ณ€์ˆ˜์ด๋‹ค.
  function displayName() {
    // displayName() ์€ ๋‚ด๋ถ€ ํ•จ์ˆ˜์ด๋ฉฐ, ํด๋กœ์ €๋‹ค.
    console.log(name); // ๋ถ€๋ชจ ํ•จ์ˆ˜์—์„œ ์„ ์–ธ๋œ ๋ณ€์ˆ˜๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค.
  }
  displayName();
}
init();
// ์ถœ๋ ฅ ๊ฒฐ๊ณผ: SeongHo

๋‹ค์Œ๊ณผ ๊ฐ™์ด displayName() ๋‚ด๋ถ€์—” ์ž์‹ ๋งŒ์˜ ์ง€์—ญ ๋ณ€์ˆ˜๊ฐ€ ์—†์ง€๋งŒ , ๋ถ€๋ชจ ํ•จ์ˆ˜ init()์—์„œ ์„ ์–ธ๋œ ๋ณ€์ˆ˜ name์— ์ ‘๊ทผ์ด ๊ฐ€๋Šฅํ•˜๋‹ค. ๋งŒ์•ฝ ์ž์‹ ๋งŒ์˜ name ๋ณ€์ˆ˜๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ๋‹ค๋ฉด, name ๋Œ€์‹ ์— this.name์„ ์‚ฌ์šฉํ–ˆ์„ ๊ฒƒ์ด๋‹ค.

๐Ÿ“Œ ์ฐธ๊ณ 

lexical

์–ดํœ˜์  ๋ฒ”์œ„ ์ง€์ •(lexical scoping) ๊ณผ์ •์—์„œ ๋ณ€์ˆ˜๊ฐ€ ์–ด๋””์—์„œ ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•œ์ง€ ์•Œ๊ธฐ ์œ„ํ•ด ๊ทธ ๋ณ€์ˆ˜๊ฐ€ ์†Œ์Šค์ฝ”๋“œ ๋‚ด ์–ด๋””์—์„œ ์„ ์–ธ๋˜์—ˆ๋Š”์ง€ ๊ณ ๋ คํ•œ๋‹ค๋Š” ๊ฒƒ์„ ์˜๋ฏธ

 

๐Ÿ“ ํด๋กœ์ € ์˜ˆ์ œ ์ฝ”๋“œ

์ค‘์ฒฉ๋œ ํ•จ์ˆ˜๋Š” ์™ธ๋ถ€ ๋ฒ”์œ„(scope)์—์„œ ์„ ์–ธํ•œ ๋ณ€์ˆ˜์—์„œ๋„ ์ ‘๊ทผ ๊ฐ€๋Šฅํ•˜๋‹ค.

function selectName() {
  const name = 'SeongHo';
  function displayName() {
    console.log(name);
  }
  return displayName;
}

// myName๋ณ€์ˆ˜์— displayName์„ ๋ฆฌํ„ดํ•จ(์ฐธ์กฐ ๊ฐ’ ์ „๋‹ฌ)
// ์œ ํšจ๋ฒ”์œ„์˜ ์–ดํœ˜์  ํ™˜๊ฒฝ์„ ์œ ์ง€
const myName = selectName();
// ๋ฆฌํ„ด๋œ displayName ํ•จ์ˆ˜๋ฅผ ์‹คํ–‰(name ๋ณ€์ˆ˜์— ์ ‘๊ทผ)
myName();

์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๋Š” ํ•จ์ˆ˜๋ฅผ ๋ฆฌํ„ดํ•˜๊ณ , ๋ฆฌํ„ดํ•˜๋Š” ํ•จ์ˆ˜๊ฐ€ ํด๋กœ์ €๋ฅผ ํ˜•์„ฑํ•˜๋ฏ€๋กœ  selectName() ํ•จ์ˆ˜์˜ ์‹คํ–‰์ด ๋๋‚˜๋”๋ผ๋„ name ๋ณ€์ˆ˜์— ์ ‘๊ทผ์ด ๊ฐ€๋Šฅํ•˜๋‹ค.

 

๐Ÿ“ class์—์„œ private ํ•„๋“œ๋ฅผ ์‚ฌ์šฉํ•œ ์ฝ”๋“œ

class selectName {
  #name = 'SeongHo';
  displayName() {
    console.log(this.#name);
  }
}

const myName = new selectName();
myName.displayName();

 

๋งˆ๋ฌด๋ฆฌ..

์•„์ง ์ „๋ถ€๋ฅผ ์ดํ•ดํ•˜๊ธฐ์—๋Š” ์–ด๋ ค์›€์ด ๋งŽ๋‹ค.. ํ•˜ํ•˜

ํด๋กœ์ €๋ฅผ ์™„๋ฒฝํ•˜๊ฒŒ ์ดํ•ดํ•˜๋ ค๋ฉด ์Šค์ฝ”ํ”„์™€ ๋ ‰์‹œ์ปฌ ํ™˜๊ฒฝ์— ๋Œ€ํ•ด์„œ ๋” ๊ณต๋ถ€๊ฐ€ ํ•„์š”ํ•˜๋‹ค..

ํ•˜๋‚˜ํ•˜๋‚˜์”ฉ ์ง€์‹์„ ์Šต๋“ํ•˜๋ฉด์„œ ๋ธ”๋กœ๊ทธ์— ํฌ์ŠคํŒ…ํ•˜๋‹ค ๋ณด๋ฉด ๊ดœ์ฐฎ์€ ๊ฐœ๋ฐœ์ž๊ฐ€ ๋˜์ง€ ์•Š์„๊นŒโ“โ“

์ด ๊ธ€์„ ๋ณด๊ณ  ์ž˜๋ชป๋œ ๋ถ€๋ถ„์— ๋Œ€ํ•œ ๋Œ“๊ธ€์„ ๋‚จ๊ฒจ์ฃผ์‹œ๋ฉด ๊ฐ์‚ฌํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.

 

๐Ÿ“š ์ฐธ๊ณ  ๋ฌธํ—Œ

https://developer.mozilla.org/ko/docs/Web/JavaScript/Closures

 

ํด๋กœ์ € - JavaScript | MDN

ํด๋กœ์ €๋Š” ํ•จ์ˆ˜์™€ ํ•จ์ˆ˜๊ฐ€ ์„ ์–ธ๋œ ์–ดํœ˜์  ํ™˜๊ฒฝ์˜ ์กฐํ•ฉ์ด๋‹ค. ํด๋กœ์ €๋ฅผ ์ดํ•ดํ•˜๋ ค๋ฉด ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ๊ฐ€ ์–ด๋–ป๊ฒŒ ๋ณ€์ˆ˜์˜ ์œ ํšจ๋ฒ”์œ„๋ฅผ ์ง€์ •ํ•˜๋Š”์ง€(Lexical scoping)๋ฅผ ๋จผ์ € ์ดํ•ดํ•ด์•ผ ํ•œ๋‹ค.

developer.mozilla.org