λ³Έλ¬Έ λ°”λ‘œκ°€κΈ°

JavaScript

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

λ°˜μ‘ν˜•

🚨 μ•„λž˜ λ”λ³΄κΈ°λŠ” 개인적 곡뢀λ₯Ό μœ„ν•΄ κΈ°λ‘ν•œ ν”μ μž…λ‹ˆλ‹€. 

 

더보기

책을 읽기 μ „ μ˜ˆμƒλ˜λŠ” μ „μ—­ λ³€μˆ˜μ˜ 문제점

 λ„€μž„μŠ€νŽ˜μ΄μŠ€ ν΄λ£¨μ…˜

 μ„œλ‘œλ‹€λ₯Έ μ‚¬λžŒμ΄ μ„ μ–Έν•œ λ³€μˆ˜κ°€ scopeλ₯Ό 톡해 μ „μ—­λ³€μˆ˜μ— μ ‘κ·Όν•  μˆ˜λ„ μžˆκΈ°μ—  μ „μ—­λ³€μˆ˜μ˜ 경우 ν˜‘μ—… μ‹œ 문제λ₯Ό μ΄ˆλž˜ν•  κ°€λŠ₯성이 μžˆμŠ΅λ‹ˆλ‹€. ν˜„μž¬λ‘œμ„œλŠ” 이것이 μ „λΆ€

 

책을 읽은 ν›„ λ¨Έλ¦Ώμ†μ—μ„œμ˜ 첫 인좜 

intro λ³€μˆ˜μ™€ λ³€μˆ˜μ˜ 생λͺ…μ£ΌκΈ°

  • λ³€μˆ˜λŠ” λ©”λͺ¨λ¦¬μ— ν• λ‹Ήλ˜λŠ” 값을 μ°Ύμ•„κ°€λŠ” μ‹λ³„μžμ˜ 역할을 ν•©λ‹ˆλ‹€. 
  • μ „μ—­λ³€μˆ˜μ˜ 경우 생λͺ…μ£ΌκΈ°κ°€ μ „μ—­ 객체의 생λͺ…주기와 λ™μΌν•©λ‹ˆλ‹€. 이 말은 λΈŒλΌμš°μ €λ₯Ό 닫을 λ•Œ μ „μ—­λ³€μˆ˜κ°€ μ†Œλ©Έν•œλ‹€λŠ” μ˜λ―Έμž…λ‹ˆλ‹€. λ©”λͺ¨λ¦¬λ₯Ό μ˜€λžœκΈ°κ°„λ™μ•ˆ μ°¨μ§€ν•˜κΈ° λ•Œλ¬Έμ— μ „μ—­λ³€μˆ˜κ°€ λ§Žμ•„μ§€λ©΄ λ©”λͺ¨λ¦¬ ν™œμš©λ„κ°€ λ–¨μ–΄μ§ˆ 수 μžˆλŠ”κ²ƒμž…λ‹ˆλ‹€. 
  • ν•¨μˆ˜ 속 μ§€μ—­λ³€μˆ˜μ˜ 경우 ν•¨μˆ˜ μŠ€μ½”ν”„μ•ˆμ— λ“±λ‘λ˜λ©° 생λͺ…μ£ΌκΈ°μ˜ 경우 ν•¨μˆ˜μ˜ 호좜과 ν•¨κ»˜ μ‹œμž‘λ˜κ³  λ°˜ν™˜λ¬Έμ΄ μ‹€ν–‰λ˜κ³ λ‚˜λ©΄ μ†Œλ©Έν•©λ‹ˆλ‹€.(ν•¨μˆ˜μ˜ 생λͺ…주기와 λ™μΌν•˜λ‹€κ³  λ³Ό 수 μžˆμŠ΅λ‹ˆλ‹€.)
  • μžλ°”μŠ€ν¬λ¦½νŠΈκ°€ μ‹€ν–‰λ˜λ©΄ μžλ°”μŠ€ν¬λ¦½νŠΈ 엔진은 μ „μ—­ 객체λ₯Ό λ‘œλ“œ?ν•˜κ³  μ „μ—­λ³€μˆ˜, ν•¨μˆ˜μ˜ 선언을 μ „μ—­ μŠ€μ½”ν”„μ— λ“±λ‘ν•˜κ³  λŸ°νƒ€μž„μ΄ μžλ°”μŠ€ν¬λ¦½νŠΈ μ½”λ“œλ₯Ό ν•œμ€„ν•œμ€„ μ‹€ν–‰ν•©λ‹ˆλ‹€.  

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

  • μ „μ—­λ³€μˆ˜λ₯Ό μ‚¬μš©ν•œλ‹€λŠ” 것은 μ•”묡적 κ²°ν•© μš©μΈν•˜λŠ” 것 μž…λ‹ˆλ‹€. μ½”λ“œ λͺ¨λ“  μ˜μ—­μ—μ„œ ν•΄λ‹Ή λ³€μˆ˜λ₯Ό μ°Έμ‘°ν•  수 있고 μˆ˜μ •ν•  수 μžˆλ‹€λŠ” 것 μž…λ‹ˆλ‹€. + μ½”λ“œμ˜ 가독성을 μžƒκ²Œ λ©λ‹ˆλ‹€.
  • namespace pollution => ??
  • κΈ΄ 생λͺ…μ£ΌκΈ° μ΄κ²ƒμ€ κΈ° introμ—μ„œ μ–ΈκΈ‰ν•œ λΈŒλΌμš°μ €λ₯Ό λ‹«κΈ° μ „κΉŒμ§€ λ³€μˆ˜μ˜ 값이 λ©”λͺ¨λ¦¬λ₯Ό μ°¨μ§€ν•˜κ³  있기 λ•Œλ¬Έμ— λ©”λͺ¨λ¦¬ ν™œμš© μΈ‘λ©΄μ—μ„œ λ¬Έμ œκ°€ μžˆμŒμ„ μ˜λ―Έν•©λ‹ˆλ‹€. 

TAIL λ¬΄λΆ„λ³„ν•œ μ „μ—­ λ³€μˆ˜λ₯Ό ν•΄κ²°ν•  수 μžˆλŠ” 방법

  • μ¦‰μ‹œ μ‹€ν–‰ν•¨μˆ˜
  • type = "module" μžλ°”μŠ€ν¬λ¦½νŠΈ νŒŒμΌμ„ λͺ¨λ“ˆλ‘œ νƒ€μž… μ§€μ •ν•˜μ—¬ λΆˆλŸ¬μ˜¨λ‹€λ©΄ λͺ¨λ“ˆμ΄λΌλŠ” λ‹€λ₯Έ μŠ€μ½”ν”„μ— λ“±λ‘λ˜μ–΄ ...

인좜과 ν…μŠ€νŠΈλ₯Ό λΉ„κ΅ν•˜λ©° λ‹€μ‹œ 정리

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

λ³€μˆ˜λŠ” 생물과 μœ μ‚¬ν•˜κ²Œ μƒμ„±λ˜κ³  μ†Œλ©Έλ˜λŠ” 생λͺ…μ£ΌκΈ°κ°€ μžˆμŠ΅λ‹ˆλ‹€. 

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

λŒ€λΆ€λΆ„μ˜ 지역 λ³€μˆ˜μ˜ 경우 ν•¨μˆ˜κ°€ 호좜되면 μƒμ„±λ˜κ³  ν•¨μˆ˜κ°€ μ’…λ£Œν•˜λ©΄ μ†Œλ©Έν•©λ‹ˆλ‹€.(지역 λ³€μˆ˜μ˜ 생λͺ… μ£ΌκΈ°λŠ” ν•¨μˆ˜μ˜ 생λͺ… 주기와 μΌμΉ˜ν•œλ‹€κ³  ν•  수 있겠죠.)

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

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

지역 λ³€μˆ˜ xλŠ” foo ν•¨μˆ˜λ₯Ό ν˜ΈμΆœν•˜λ©΄ μƒμ„±λ©λ‹ˆλ‹€. fooν•¨μˆ˜λ₯Ό ν˜ΈμΆœν•΄μ•Ό ν•¨μˆ˜ λ‚΄λΆ€μ˜ λ³€μˆ˜ 선언문이 μ‹€ν–‰λ˜κΈ° λ•Œλ¬Έμž…λ‹ˆλ‹€. ν•¨μˆ˜ λ‚΄λΆ€μ—μ„œ μ„ μ–Έν•œ λ³€μˆ˜λŠ” ν•¨μˆ˜κ°€ 호좜된 직후, μ½”λ“œκ°€ ν•œ 쀄씩 μ‹€ν–‰λ˜κΈ° 이전에 μžλ°”μŠ€ν¬λ¦½νŠΈ 엔진에 μ˜ν•΄ λ¨Όμ € μ‹€ν–‰λ©λ‹ˆλ‹€. 

μœ„ μ½”λ“œμ˜ μ‹€ν–‰ μˆœμ„œλŠ” μ•„λž˜μ™€ κ°™μŠ΅λ‹ˆλ‹€. 

fooν•¨μˆ˜λ₯Ό 호좜
μžλ°”μŠ€ν¬λ¦½νŠΈ 엔진에 μ˜ν•΄ λ³€μˆ˜ xλ₯Ό μ„ μ–Έν•˜κ³  undefined둜 μ΄ˆκΈ°ν™”
ν•¨μˆ˜ body의 μ½”λ“œλ₯Ό ν•œμ€„μ”© 순차적으둜 μ‹€ν–‰
x에 값을 ν• λ‹Ήν•˜λŠ” μ½”λ“œλ₯Ό λ§Œλ‚˜λ©΄ λ³€μˆ˜μ— 값이 할당됨
return으둜 xλ₯Ό λ°˜ν™˜ν•˜λ©΄ ν•¨μˆ˜κ°€ μ’…λ£Œλ˜μ–΄ λ³€μˆ˜μ˜ 생λͺ… 주기도 μ’…λ£Œλ˜μ–΄ μ†Œλ©Έ

μœ„μ˜ κ²½μš°μ™€λŠ” 달리 지역 λ³€μˆ˜κ°€ ν•¨μˆ˜λ³΄λ‹€ 였래 μƒμ‘΄ν•˜λŠ” κ²½μš°λ„ 있기 λ•Œλ¬Έμ— ν•¨μˆ˜ λ‚΄λΆ€μ—μ„œ μ„ μ–Έλœ 지역 λ³€μˆ˜μ˜ 생λͺ… μ£ΌκΈ°κ°€ ν•¨μˆ˜μ˜ 생λͺ…주기와 μΌμΉ˜ν•œλ‹€λŠ” 것이 100% 참이라고 ν•  μˆ˜λŠ” μ—†μŠ΅λ‹ˆλ‹€.  μ•„λž˜μ˜ 경우λ₯Ό λ³΄μ‹œμ£ .

const makeCounter = () => {
	let value = 0;
    return {
		increase: () => {
			value = value + 1;
		},
        decrease: () => {
			value = value - 1;
		},
        getValue: () => value
	}
}

const counter1 = makeCounter();
counter1 // {increase : f, decrease: f, getValue: f}

 

counter1λΌλŠ” λ³€μˆ˜μ—λŠ” makeCounterν•¨μˆ˜μ˜ return κ°’(ν•¨μˆ˜ 바디에 μ„ μ–Έλœ λ³€μˆ˜λ₯Ό μ°Έμ‘°ν•˜λŠ” λ©”μ„œλ“œλ₯Ό κ°€μ§€λŠ” 객체)을 ν• λ‹Ήν•˜μ˜€κΈ° λ•Œλ¬Έμ— ν•¨μˆ˜ 호좜 이후에도 κ³„μ†ν•˜μ—¬ value λ³€μˆ˜μ— μ ‘κ·Όν•  수 μžˆλŠ” 것을 μ•Œ 수 μžˆμŠ΅λ‹ˆλ‹€. 이 κ²½μš°μ— 지역 λ³€μˆ˜μ˜ 생λͺ…μ£ΌκΈ°λŠ” λ©”λͺ¨λ¦¬ 곡간이 ν™•λ³΄λœ μ‹œμ λΆ€ν„° λ©”λͺ¨λ¦¬ 곡간이 ν•΄μ œλ˜μ–΄ κ°€μš© λ©”λͺ¨λ¦¬ 풀에 λ°˜ν™˜λ˜λŠ” μ‹œμ κΉŒμ§€λΌκ³  ν•  수 μžˆμŠ΅λ‹ˆλ‹€. λ©”λͺ¨λ¦¬ 곡간은 λˆ„κ΅°κ°€κ°€ μ°Έμ‘°ν•˜κ³  μžˆμ§€ μ•ŠμœΌλ©΄ 가비지 μ½œλ ‰ν„°μ— μ˜ν•΄ ν•΄μ œλ˜μ–΄ κ°€μš© λ©”λͺ¨λ¦¬μ— λ°˜ν™˜λ˜λ―€λ‘œ λˆ„κ΅°κ°€κ°€ μ§€μ—­λ³€μˆ˜λ₯Ό μ°Έμ‘°ν•˜κ³  μžˆλ‹€λ©΄ ν•΄λ‹Ή λ³€μˆ˜λŠ” μ†Œλ©Έν•˜μ§€ μ•ŠλŠ” κ²ƒμž…λ‹ˆλ‹€.   

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

var ν‚€μ›Œλ“œλ‘œ μ„ μ–Έν•œ μ „μ—­ λ³€μˆ˜λŠ” μ „μ—­ 객체의 ν”„λ‘œνΌν‹°κ°€ λ©λ‹ˆλ‹€. μ΄λŠ” μ „μ—­ λ³€μˆ˜μ˜ 생λͺ… μ£ΌκΈ°κ°€ μ „μ—­ 객체의 생λͺ… 주기와 μΌμΉ˜ν•œλ‹€λŠ” 것을 μ˜λ―Έν•©λ‹ˆλ‹€. λΈŒλΌμš°μ €μ˜ 경우 μ „μ—­κ°μ²΄λŠ” windowμ΄λ―€λ‘œ μ „μ—­ λ³€μˆ˜λŠ” window의 ν”„λ‘œνΌν‹° 인 κ²ƒμž…λ‹ˆλ‹€. (λΈŒλΌμš°μ € μ’…λ£Œμ‹œ μ „μ—­ λ³€μˆ˜κ°€ μ†Œλ©Έν•œλ‹€κ³  ν•  수 μžˆμŠ΅λ‹ˆλ‹€.)

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

  • 암묡적 κ²°ν•© : λͺ¨λ“  μ½”λ“œκ°€ μ „μ—­ λ³€μˆ˜λ₯Ό μ°Έμ‘°ν•˜κ³  λ³€κ²½ν•  수 μžˆλ‹€λŠ” 것 μž…λ‹ˆλ‹€. λ³€μˆ˜μ˜ 유효 λ²”μœ„κ°€ 크면 μ½”λ“œμ˜ 가독성은 떨어지고 μ˜λ„μΉ˜μ•Šκ²Œ μƒνƒœκ°€ 변경될 수 μžˆμŠ΅λ‹ˆλ‹€.
  • κΈ΄ 생λͺ… μ£ΌκΈ° : μ „μ—­ λ³€μˆ˜λŠ” λΈŒλΌμš°μ € μ’…λ£Œμ— μ†Œλ©Έλ˜λ―€λ‘œ 생λͺ…μ£ΌκΈ°κ°€ κΉλ‹ˆλ‹€. 생λͺ…μ£ΌκΈ°κ°€ κΈΈ 수둝 μ „μ—­ λ³€μˆ˜μ˜ μƒνƒœλ₯Ό λ³€κ²½ν•  수 μžˆλŠ” μ‹œκ°„κ³Ό 기회 λ˜ν•œ λ§Žμ•„μ§‘λ‹ˆλ‹€. λ˜ν•œ λ©”λͺ¨λ¦¬ λ¦¬μ†ŒμŠ€λ„ κΈ΄ μ‹œκ°„ μ†ŒλΉ„ν•˜κΈ°μ— λ©”λͺ¨λ¦¬μ  μΈ‘λ©΄μ—μ„œ λΉ„νš¨μœ¨ μ μž…λ‹ˆλ‹€. 
  • μŠ€μ½”ν”„ 체인 μƒμ—μ„œ 쒅점에 쑴재 : μ „μ—­ λ³€μˆ˜λŠ” μŠ€μ½”ν”„ 체인 μƒμ—μ„œ 쒅점에 μœ„μΉ˜ν•˜κΈ°μ— κ°€μž₯ λ§ˆμ§€λ§‰μ— κ²€μƒ‰λ©λ‹ˆλ‹€. 
  • λ„€μž„μŠ€νŽ˜μ΄μŠ€ μ˜€μ—Ό : 파일이 λΆ„λ¦¬λ˜μ–΄ μžˆμ–΄λ„ ν•˜λ‚˜μ˜ μ „μ—­ μŠ€μ½”ν”„λ₯Ό κ³΅μœ ν•œλ‹€λŠ” 것이 μžλ°”μŠ€ν¬λ¦½νŠΈμ˜ κ°€μž₯ 큰 문제점인데 λ§Œμ•½ λ‹€λ₯Έ νŒŒμΌμ—μ„œ 같은 μ΄λ¦„μ˜ μ „μ—­ λ³€μˆ˜λ‚˜ ν•¨μˆ˜κ°€ 같은 μŠ€μ½”ν”„μ— μžˆμ„ 경우 μ „ν˜€ λ‹€λ₯Έ κ²°κ³Όλ₯Ό λ³Ό κ°€λŠ₯성이 μžˆμŠ΅λ‹ˆλ‹€.

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

  • μ¦‰μ‹œ μ‹€ν–‰ ν•¨μˆ˜ : ν•¨μˆ˜μ˜ μ •μ˜μ™€ λ™μ‹œμ— ν˜ΈμΆœλ˜λŠ” μ¦‰μ‹œ μ‹€ν–‰ ν•¨μˆ˜λŠ” 단 ν•œ 번만 ν˜ΈμΆœλ©λ‹ˆλ‹€. λͺ¨λ“  μ½”λ“œλ₯Ό μ¦‰μ‹œ μ‹€ν–‰ ν•¨μˆ˜λ‘œ 감싸면 λͺ¨λ“  λ³€μˆ˜λŠ” 지역 λ³€μˆ˜κ°€ λ©λ‹ˆλ‹€.
    (function(){
    	var foo = 10; // μ¦‰μ‹œ μ‹€ν–‰ ν•¨μˆ˜μ˜ 지역 λ³€μˆ˜
        // ...
    }());
    
    console.log(foo); // ReferenceError: foo is not defined​
  • λ„€μž„μŠ€νŽ˜μ΄μŠ€ 객체 : 전역에 λ„€μž„μŠ€νŽ˜μ΄μŠ€ 역할을 λ‹΄λ‹Ήν•  객체λ₯Ό μƒμ„±ν•˜κ³  μ „μ—­ λ³€μˆ˜μ²˜λŸΌ μ‚¬μš©ν•˜κ³  싢은 λ³€μˆ˜λ₯Ό ν”„λ‘œνΌν‹°λ‘œ μΆ”κ°€ν•˜λŠ” 방법.
    var MYAPP = {};
    
    MYAPP.name = 'Lee';
    
    console.log(MYAPP.name); // Lee
  • λͺ¨λ“ˆ νŒ¨ν„΄ : λͺ¨λ“ˆ νŒ¨ν„΄μ€ 클래슀λ₯Ό λͺ¨λ°©ν•΄μ„œ 관련이 μžˆλŠ” λ³€μˆ˜μ™€ ν•¨μˆ˜λ₯Ό λͺ¨μ•„ μ¦‰μ‹œ μ‹€ν–‰ ν•¨μˆ˜λ‘œ 감싸 ν•˜λ‚˜μ˜ λͺ¨λ“ˆμ„ λ§Œλ“œλŠ” κ²ƒμž…λ‹ˆλ‹€. λͺ¨λ“ˆ νŒ¨ν„΄μ€ ν΄λ‘œμ €λ₯Ό 기반으둜 λ™μž‘ν•˜λ©° μ „μ—­ λ³€μˆ˜μ˜ μ–΅μ œλŠ” λ¬Όλ‘  μΊ‘μŠν™”κΉŒμ§€ κ΅¬ν˜„ν•  수 μžˆμŠ΅λ‹ˆλ‹€.(μΊ‘μŠν™”λŠ” 객체의 νŠΉμ • ν”„λ‘œνΌν‹°μ™€ λ©”μ„œλ“œλ₯Ό μ€λ‹‰ν•˜λŠ”λ° μ‚¬μš©λ˜κΈ°λ„ ν•©λ‹ˆλ‹€.) λŒ€λΆ€λΆ„μ˜ 객체지ν–₯ ν”„λ‘œκ·Έλž˜λ° μ–Έμ–΄μ™€λŠ” 달리 μ ‘κ·Ό μ œν•œμžκ°€ μ—†κΈ° λ•Œλ¬Έμ— λͺ¨λ“ˆ νŒ¨ν„΄μ„ ν†΅ν•΄μ„œ μ •λ³΄μ˜ 곡개 μ—¬λΆ€λ₯Ό κ²°μ •ν•  수 μžˆμŠ΅λ‹ˆλ‹€.
    var makeCounter = (function(){
    	let value = 0;
        return {
    		increase: () => {
    			value = value + 1;
    		},
            decrease: () => {
    			value = value - 1;
    		},
            getValue: () => value
    	};
    }());
     value λ³€μˆ˜λŠ” μ™ΈλΆ€μ—μ„œ μ ‘κ·Όν•  수 μ—†λŠ” private member이고, makeCounter ν•¨μˆ˜λŠ” 외뢀에 λ…ΈμΆœν•˜κ³  싢은 λ³€μˆ˜λ‚˜ ν•¨μˆ˜λ₯Ό 객체에 λ‹΄μ•„ λ°˜ν™˜ν•˜κ³  μ΄λ•Œ λ°˜ν™˜λ˜λŠ” 객체의 ν”„λ‘œνΌν‹°λŠ” 외뢀에 λ…ΈμΆœλ˜λŠ” 퍼블릭 λ©€λ²„μž…λ‹ˆλ‹€. 
  • ES6 λͺ¨λ“ˆ : es6 λͺ¨λ“ˆμ€ 파일 자체의 λ…μžμ μΈ λͺ¨λ“ˆ μŠ€μ½”ν”„λ₯Ό μ œκ³΅ν•˜λ―€λ‘œ λͺ¨λ“ˆ λ‚΄μ—μ„œ var ν‚€μ›Œλ“œλ‘œ μ„ μ–Έν•œ λ³€μˆ˜λŠ” 더이상 μ „μ—­ λ³€μˆ˜κ°€ μ•„λ‹ˆλ©° window객체의 ν”„λ‘œνΌν‹°λ„ μ•„λ‹ˆκ²Œ λ©λ‹ˆλ‹€. scriptνƒœν¬μ— type="module" 속성을 μΆ”κ°€ν•˜λ©΄ λ‘œλ“œλœ μžλ°”μŠ€ν¬λ¦½νŠΈ νŒŒμΌμ€ λͺ¨λ“ˆλ‘œμ„œ λ™μž‘ν•©λ‹ˆλ‹€.(λͺ¨λ“ˆμ˜ 파일 ν™•μž₯μžλŠ” mjsλ₯Ό ꢌμž₯ν•œλ‹€κ³  ν•©λ‹ˆλ‹€. )
    <script type="module" src="app.mjs"></script>​

좜처: λͺ¨λ˜ μžλ°”μŠ€ν¬λ¦½νŠΈ Deep Dive

λ°˜μ‘ν˜•