[πŸ“– λͺ¨λ˜ μžλ°”μŠ€ν¬λ¦½νŠΈ λ”₯λ‹€μ΄λΈŒ] 14μž₯. μ „μ—­ λ³€μˆ˜μ˜ 문제점

λ…Έμ˜μ™„Β·2023λ…„ 10μ›” 23일
0

JavaScript(Deep Dive)

λͺ©λ‘ 보기
9/23
post-thumbnail

μ „μ—­ λ³€μˆ˜μ˜ 문제점

  • μ „μ—­ λ³€μˆ˜μ˜ λ¬΄λΆ„λ³„ν•œ μ‚¬μš©μ€ μœ„ν—˜ν•˜λ‹€ μ „μ—­ λ³€μˆ˜λ₯Ό λ°˜λ“œμ‹œ μ‚¬μš©ν•΄μ•Ό ν•  이유λ₯Ό 찾지 λͺ»ν•œλ‹€λ©΄ 지역 λ³€μˆ˜λ₯Ό μ‚¬μš©ν•΄μ•Ό ν•œλ‹€.

1. λ³€μˆ˜μ˜ 생λͺ… μ£ΌκΈ°

1-1. 지역 λ³€μˆ˜μ˜ 생λͺ…μ£ΌκΈ°

λ³€μˆ˜λŠ” 선언에 μ˜ν•΄ μƒμ„±λ˜κ³  할당을 톡해 값을 κ°–λŠ”λ‹€. 그리고 μ–Έμ  κ°€ μ†Œλ©Έν•œλ‹€. μ†Œλ©Έμ΄ μ•ˆλœλ‹€λ©΄ ν•œλ²ˆ μ„ μ–Έλœ λ³€μˆ˜λŠ” ν”„λ‘œκ·Έλž˜λ° μ’…λ£Œν•˜μ§€ μ•ŠλŠ” ν•œ μ˜μ›νžˆ λ©”λͺ¨λ¦¬ 곡간을 μ μœ ν•˜κ²Œ λœλ‹€.

λ³€μˆ˜λŠ” μžμ‹ μ΄ μ„ μ–Έλ˜ μœ„μΉ˜μ—μ„œ μƒμ„±λ˜κ³  μ†Œλ©Έν•œλ‹€. μ „μ—­ λ³€μˆ˜μ˜ 생λͺ…μ£ΌκΈ°λŠ” μ• ν”Œλ¦¬μΌ€μ΄μ…˜μ˜ 생λͺ… 주기와 κ°™λ‹€. ν•˜μ§€λ§Œ ν•¨μˆ˜ λ‚΄λΆ€μ—μ„œ μ„ μ–Έλœ 지역 λ³€μˆ˜λŠ” ν•¨μˆ˜κ°€ 호좜되면 μƒμ„±λ˜κ³  ν•¨μˆ˜κ°€ μ’…λ£Œν•˜λ©΄ μ†Œλ©Έλœλ‹€.

fuction foo() {
	var x = "local";
	console.log(x)/ // local
	return x;

foo();
console.log(x); // ReferenceError: x is not defined

지역 λ³€μˆ˜ xλŠ” foo ν•¨μˆ˜κ°€ 호좜되기 μ΄μ „κΉŒμ§€λŠ” μƒμ„±λ˜μ§€ μ•ŠλŠ”λ‹€. foo ν•¨μˆ˜λ₯Ό ν˜ΈμΆœν•˜μ§€ μ•ŠμœΌλ©΄ ν•¨μˆ˜ λ‚΄λΆ€μ˜ λ³€μˆ˜ 선언문이 μ‹€ν–‰λ˜μ§€ μ•ŠκΈ° λ•Œλ¬Έμ΄λ‹€.

λ³€μˆ˜ 선언은 선언문이 어디에 μžˆλ“  상관 없이 κ°€μž₯ λ¨Όμ € μ‹€ν–‰λœλ‹€. λ‹€μ‹œ 말해, λ³€μˆ˜ 선언은 μ½”λ“œκ°€ ν•œ 쀄씩 순차적으둜 μ‹€ν–‰λ˜λŠ” μ‹œμ μΈ λŸ°νƒ€μž„μ— μ‹€ν–‰λ˜λŠ” 것이 μ•„λ‹ˆλΌ λŸ°νƒ€μž„ 이전 λ‹¨κ³„μ—μ„œ μžλ°”μŠ€ν¬λ¦½νŠΈ 엔진에 μ˜ν•΄ λ¨Όμ € μ‹€ν–‰λœλ‹€. 그런데 μ—„λ°€νžˆ λ§ν•˜μžλ©΄ μœ„ μ„€λͺ…은 μ „μ—­ λ³€μˆ˜μ— ν•œμ •

ν•¨μˆ˜ λ‚΄λΆ€μ—μ„œ μ„ μ–Έν•œ λ³€μˆ˜λŠ” ν•¨μˆ˜κ°€ ν˜ΈμΆœλ˜μ—ˆκ³  ν•¨μˆ˜ λͺΈμ²΄μ˜ μ½”λ“œκ°€ ν•œ 쀄씩 순차적으둜 μ‹€ν–‰λ˜κΈ° 이전에 μžλ°”μŠ€ν¬λ¦½νŠΈ 엔진에 μ˜ν•΄ λ¨Όμ € μ‹€ν–‰λœλ‹€. 즉, 지역 λ³€μˆ˜μ˜ 생λͺ… μ£ΌκΈ°λŠ” ν•¨μˆ˜ 생λͺ… 주기와 μΌμΉ˜ν•œλ‹€.

var x = "global";
function foo() {
  console.log(x); // undefined
  var x = "local";
}

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

ν•¨μˆ˜κ°€ 호좜된 직 ν›„, ν•¨μˆ˜ 내뢀에 지역 λ³€μˆ˜λŠ” μ„ μ–Έλ˜μ—ˆκ³  undefined둜 μ΄ˆκΈ°ν™”λ˜μ–΄ μžˆλ‹€. λ³€μˆ˜ 할당문이 μ‹€ν–‰λ˜κΈ° μ΄μ „κΉŒμ§€λŠ” undefined 값을 κ°–λŠ”λ‹€.

ν˜Έμ΄μŠ€νŒ…μ€ μŠ€μ½”ν”„λ₯Ό λ‹¨μœ„λ‘œ λ™μž‘ν•œλ‹€. 즉, ν˜Έμ΄μŠ€νŒ…μ€ λ³€μˆ˜ 선언이 μŠ€μ½”ν”„μ˜ μ„ λ‘λ‘œ λŒμ–΄ μ˜¬λ €μ§„ κ²ƒμ²˜λŸΌ λ™μž‘ν•˜λŠ” μžλ°”μŠ€ν¬λ¦½νŠΈ 고유의 νŠΉμ§•μ„ λ§ν•œλ‹€.

1-2. μ „μ—­ λ³€μˆ˜μ˜ 생λͺ…μ£ΌκΈ°

λΈŒλΌμš°μ € ν™˜κ²½μ—μ„œ μ „μ—­ κ°μ²΄λŠ” window var ν‚€μ›Œλ“œλ‘œ μ„ μ–Έν•œ μ „μ—­ λ³€μˆ˜λŠ” μ „μ—­ 객체 window의 ν”„λ‘œνΌν‹°λ‹€. μ „μ—­ 객체 windowλŠ” μ›ΉνŽ˜μ΄μ¦ˆλ₯Ό λ‹«κΈ° μ „κΉŒμ§€ μœ νš¨ν•˜λ‹€.

λ”°λΌμ„œ λΈŒλΌμš°μ € ν™˜κ²½μ—μ„œ var ν‚€μ›Œλ“œλ‘œ μ„ μ–Έν•œ μ „μ—­ λ³€μˆ˜λŠ” μ›ΉνŽ˜μ΄μ§€λ₯Ό 닫을 λ•ŒκΉŒμ§€ μœ νš¨ν•˜λ‹€. 즉, var ν‚€μ›Œλ“œλ‘œ μ„ μ–Έν•œ μ „μ—­ λ³€μˆ˜μ˜ 생λͺ… μ£ΌκΈ°λŠ” μ „μ—­ 객체의 생λͺ… 주기와 μΌμΉ˜ν•˜λ‹€.

πŸ’‘ μ „μ—­ κ°μ²΄λž€ ?

μ „μ—­ κ°μ²΄λŠ” μ½”λ“œκ°€ μ‹€ν–‰λ˜κΈ° 이전 단계에 μžλ°”μŠ€ν¬λ¦½νŠΈ 엔진에 μ˜ν•΄ μ–΄λ–€ 객체보닀도 λ¨Όμ € μƒμ„±λ˜λŠ” νŠΉμˆ˜ν•œ 객체닀. μ „μ—­ κ°μ²΄λŠ” ν΄λΌμ΄μ–ΈνŠΈ μ‚¬μ΄λ“œ ν™˜κ²½(λΈŒλΌμš°μ €)μ—μ„œλŠ” window, μ„œλ²„ μ‚¬μ΄λ“œ ν™˜κ²½(Node.js)μ—μ„œλŠ” global 객체λ₯Ό μ˜λ―Έν•œλ‹€. ν™˜κ²½μ— 따라 μ „μ—­ 객체λ₯Ό κ°€λ¦¬ν‚€λŠ” λ‹€μ–‘ν•œ μ‹λ³„μž(window, self, this, franes, global)κ°€ μ‘΄μž¬ν–ˆμœΌλ‚˜ ES11(ECMAScipt 11)μ—μ„œ globalThis둜 톡일 λ˜μ—ˆλ‹€.

μ „μ—­ κ°μ²΄λŠ” ν‘œμ€€ 빌트인 객체(Object, String, Number, Function, Array...)와 ν™˜κ²½μ— λ”°λ₯Έ 호슀트 객체(ν΄λΌμ΄μ–ΈνŠΈ Web API λ˜λŠ” Node.js의 호슀트 API), 그리고 var ν‚€μ›Œλ“œλ‘œ μ„ μ–Έν•œ μ „μ—­ λ³€μˆ˜μ™€ μ „μ—­ ν•¨μˆ˜λ₯Ό ν”„λ‘œνΌν‹°λ‘œ κ°–λŠ”λ‹€.

2. μ „μ—­ λ³€μˆ˜μ˜ 문제점

βœ”οΈ 암묡적 κ²°ν•©

  • λͺ¨λ“  μ½”λ“œκ°€ μ „μ—­ λ³€μˆ˜λ₯Ό μ°Έμ‘°ν•˜κ³  λ³€κ²½ν•  수 μžˆλŠ” 암묡적 κ²°ν•©

βœ”οΈ κΈ΄ 생λͺ… μ£ΌκΈ°

βœ”οΈ μŠ€μ½”ν”„ 체인 μƒμ—μ„œ 쒅점에 쑴재

  • μŠ€μ½”ν”„ 체인 μƒμ—μ„œ 쒅점이 쑴재 μ΄λŠ” λ³€μˆ˜λ₯Ό 검색할 λ•Œ μ „μ—­ λ³€μˆ˜κ°€ κ°€μž₯ λ§ˆμ§€λ§‰μ— 검색 즉, μ „μ—­ λ³€μˆ˜μ˜ 검색 속도가 κ°€μž₯ λŠλ¦¬λ‹€.

βœ”οΈ λ„€μž„μŠ€νŽ˜μ΄μŠ€ μ˜€μ—Ό

3. μ „μ—­ λ³€μˆ˜μ˜ μ‚¬μš©μ„ μ–΅μ œν•˜λŠ” 방법

  • μ „μ—­ λ³€μˆ˜μ˜ λ¬΄λΆ„λ³„ν•œ μ‚¬μš©μ€ μœ„ν—˜ν•˜λ‹€. μ „μ—­ λ³€μˆ˜λ₯Ό λ°˜λ“œμ‹œ μ‚¬μš©ν•΄μ•Ό ν•  이유λ₯Ό 찾지 λͺ»ν•œλ‹€λ©΄ 지역 λ³€μˆ˜λ₯Ό μ‚¬μš©ν•΄μ•Ό ν•œλ‹€. λ³€μˆ˜μ˜ μŠ€μ½”ν”„λŠ” μ’μ„μˆ˜λ‘ 쒁닀

3-1. μ¦‰μ‹œ μ‹€ν–‰ ν•¨μˆ˜

  • λͺ¨λ“  μ½”λ“œλ₯Ό μ¦‰μ‹œ μ‹€ν–‰ ν•¨μˆ˜λ‘œ 감싸면 λͺ¨λ“  λ³€μˆ˜λŠ” μ¦‰μ‹œ μ‹€ν–‰ ν•¨μˆ˜μ˜ 지역 λ³€μˆ˜κ°€ λœλ‹€.
(function () {
	var foo = 10;
}());

console.log(foo); // ReferenceError: foo is not defined

3-2. λ„€μž„μŠ€νŽ˜μ΄μŠ€ 객체

  • 전역에 λ„€μž„μŠ€νŽ˜μ΄μŠ€ 역할을 λ‹΄λ‹Ήν•  객체λ₯Ό μƒμ„±ν•˜κ³  μ „μ—­ λ³€μˆ˜μ²˜λŸΌ μ‚¬μš©ν•˜κ³  싢은 λ³€μˆ˜λ₯Ό ν”„λ‘œνΌν‹°λ‘œ μΆ”κ°€ν•˜λŠ” 방법
var MYAPP = {}; // μ „μ—­ λ„€μž„μŠ€νŽ˜μ΄μŠ€ 객체

MYAPP.person = {
	name = "noh",
	address = "Seoul"
};

console.log(MYAPP.person.name); // noh

3-3. λͺ¨λ“ˆ νŒ¨ν„΄

  • λͺ¨λ“ˆ νŒ¨ν„΄μ€ 클래슀λ₯Ό λͺ¨λ°©ν•΄μ„œ 관련이 μžˆλŠ” λ³€μˆ˜μ™€ ν•¨μˆ˜λ₯Ό λͺ¨μ•„ μ¦‰μ‹œ μ‹€ν–‰ ν•¨μˆ˜λ‘œ 감싸 ν•˜λ‚˜μ˜ λͺ¨λ“ˆμ„ λ§Œλ“ λ‹€.
  • λͺ¨λ“ˆ νŒ¨ν„΄μ€ μžλ°”μŠ€ν¬λ¦½νŠΈμ˜ κ°•λ ₯ν•œ κΈ°λŠ₯인 ν΄λ‘œμ €λ₯Ό 기반으둜 λ™μž‘ν•œλ‹€. λͺ¨λ“ˆ νŒ¨ν„΄μ˜ νŠΉμ§•μ€ μ „μ—­ λ³€μˆ˜μ˜ μ–΅μ œλŠ” λ¬Όλ‘  μΊ‘μŠν™”κΉŒμ§€ κ΅¬ν˜„ν•  수 μžˆλ‹€λŠ” 것
var Counter = (function () {
	// private λ³€μˆ˜
	var num = 0;
  
  	// μ™ΈλΆ€λ‘œ κ³΅κ°œν•  λ°μ΄ν„°λ‚˜ λ©”μ„œλ“œλ₯Ό ν”„λ‘œνΌν‹°λ‘œ μΆ”κ°€ν•œ 객체λ₯Ό λ°˜ν™˜.
	return {
	increase() {
		return ++num;
    },
	decrease() {
		return --num;
    }
    };
}());

// private λ³€μˆ˜λŠ” μ™ΈλΆ€λ‘œ λ…ΈμΆœλ˜μ§€ μ•ŠλŠ”λ‹€.
console.log(Counter.num) // undefined

console.log(Counter.increase()) // 1
console.log(Counter.increase()) // 2
console.log(Counter.decrease()) // 1
console.log(Counter.decrease()) // 0

3-4. ES6 λͺ¨λ“ˆ

  • ES6 λͺ¨λ“ˆμ€ 파일 자체의 λ…μžμ μΈ λͺ¨λ“ˆ μŠ€μ½”ν”„λ₯Ό μ œκ³΅ν•œλ‹€. λ”°λΌμ„œ λͺ¨λ“ˆ λ‚΄μ—μ„œ var ν‚€μ›Œλ“œλ‘œ μ„ μ–Έν•œ λ³€μˆ˜λŠ” λ”λŠ” μ „μ—­ λ³€μˆ˜κ°€ μ•„λ‹ˆλ©° window 객체의 ν”„λ‘œνΌν‹°λ„ μ•„λ‹ˆλ‹€.
  • λͺ¨λ˜ λΈŒλΌμš°μ €(Chrome 61, FF60, SF 10.1, Edge 16 이상)μ—μ„œλŠ” ES6 λͺ¨λ“ˆμ„ μ‚¬μš©ν•  수 μžˆλ‹€. script νƒœκ·Έμ— type="module" μ–΄νŠΈλ¦¬λ·°νŠΈλ₯Ό μΆ”κ°€ν•˜λ©΄ λ‘œλ“œλœ μžλ°”μŠ€ν¬λ¦½νŠΈ νŒŒμΌμ€ λͺ¨λ“ˆλ‘œμ„œ λ™μž‘ν•œλ‹€.
<script type="module" sce="lib.mjs"></script>
  • λΈŒλΌμš°μ €μ˜ ES6 λͺ¨λ“ˆ κΈ°λŠ₯을 μ‚¬μš©ν•˜λ”λΌλ„ νŠΈλžœμŠ€νŒŒμΌλ§λ‚˜ λ²ˆλ“€λ§μ΄ ν•„μš”ν•™ λ•Œλ¬Έμ— μ•„μ§κΉŒμ§€λŠ” λΈŒλΌμš°μ €κ°€ μ§€μ›ν•˜λŠ” ES6 λͺ¨λ“ˆ κΈ°λŠ₯λ³΄λ‹€λŠ” Webpack λ“±μ˜ λͺ¨λ“ˆ λ²ˆλ“€λŸ¬λ₯Ό μ‚¬μš©ν•˜λŠ” 것이 일반적

0개의 λŒ“κΈ€