πŸ˜„ λ©΄μ ‘κ΄€: closure에 λŒ€ν•΄ μ„€λͺ…ν•΄ λ³΄μ„Έμš” 🫠 λ„€..?

κΉ€λ―Όμ•„Β·2022λ…„ 7μ›” 31일
10
post-thumbnail
post-custom-banner

λ©΄μ ‘κ΄€ μ•žμ—μ„œ λ‚΄ λͺ¨μŠ΅

λ©΄μ ‘κ΄€μ—κ²Œ 이 μ§ˆλ¬Έμ„ λ°›λŠ”λ‹€λ©΄ λŒ€λ‹΅ν•  수 μžˆμ„κΉŒ? πŸ€”
λ©΄μ ‘μ—μ„œ μ‹€μ œλ‘œ λ‚˜μ˜¬ 수 μžˆλŠ” μ£Όμ œμ΄κΈ°μ— μ˜ˆμƒν•  수 μžˆλŠ” κΌ¬λ¦¬μ§ˆλ¬ΈκΉŒμ§€ ν•œλ²ˆ μ •λ¦¬ν•΄λ³΄μž.

[λ©΄μ ‘ λŒ€λΉ„ μ˜ˆμƒ 질문] ν΄λ‘œμ € (closure)

ν΄λ‘œμ €(closure)에 λŒ€ν•΄ μ„€λͺ…ν•΄ λ³΄μ„Έμš”.

ν΄λ‘œμ €λŠ” ν•¨μˆ˜μ™€ ν•¨μˆ˜κ°€ μ„ μ–Έλœ μ–΄νœ˜μ  ν™˜κ²½μ˜ μ‘°ν•©μœΌλ‘œ μ™ΈλΆ€ ν•¨μˆ˜μ˜ λ³€μˆ˜μ— μ ‘κ·Όν•  수 μžˆλŠ” λ‚΄λΆ€ ν•¨μˆ˜μž…λ‹ˆλ‹€.


μ–΄νœ˜μ  ν™˜κ²½μ˜ 쑰합은 μ–΄λ–€ 의미이죠?

μ–΄νœ˜μ  ν™˜κ²½μ˜ μ‘°ν•©μ΄λž€ β€œλ³€μˆ˜μ™€ ν•¨μˆ˜μ˜ μ„ μ–Έ ν˜•νƒœμ˜ 쑰합”을 λ§ν•˜λŠ” κ²ƒμΈλ°μš”, μžλ°”μŠ€ν¬λ¦½νŠΈλŠ” ν•¨μˆ˜κ°€ ν˜ΈμΆœλ˜λŠ” ν™˜κ²½κ³ΌλŠ” λ³„κ°œλ‘œ, 기쑴에 μ„ μ–Έλ˜μ—ˆλ˜ ν™˜κ²½μ„ κΈ°μ€€μœΌλ‘œ λ³€μˆ˜λ₯Ό μ‘°νšŒν•˜λ €λŠ” νŠΉμ„±μ΄ 있기 λ•Œλ¬Έμž…λ‹ˆλ‹€.

즉, ν΄λ‘œμ €κ°€ μƒμ„±λœ μ‹œμ μ˜ 유효 λ²”μœ„μ— μžˆλŠ” λͺ¨λ“  지역 λ³€μˆ˜λ₯Ό μ‚¬μš©ν•˜λŠ” ν™˜κ²½μ„ λ§ν•˜λŠ” κ²ƒμž…λ‹ˆλ‹€.


ν΄λ‘œμ €μ˜ νŠΉμ§•μ„ μ„€λͺ…ν•΄ λ³΄μ„Έμš”.

ν΄λ‘œμ €λŠ” μΊ‘μŠν™”μ™€ λͺ¨λ“ˆν™”μ˜ νŠΉμ§•μ„ 가지고 μžˆμŠ΅λ‹ˆλ‹€. μ™ΈλΆ€ ν•¨μˆ˜μ˜ λ³€μˆ˜κ°€ ν•¨μˆ˜ λ°–μœΌλ‘œ λ…ΈμΆœλ˜μ§€ μ•Šμ•„ μ •λ³΄μ˜ 접근을 μ œν•œν•΄ ν΄λ‘œμ €λ‘œ μžλ°”μŠ€ν¬λ¦½νŠΈμ—μ„œ μΊ‘μŠν™”λ₯Ό κ΅¬ν˜„ν•  수 μžˆμŠ΅λ‹ˆλ‹€. λ˜ν•œ ν΄λ‘œμ €λŠ” 데이터λ₯Ό λ³΄μ‘΄ν•˜λŠ” ν•¨μˆ˜μž…λ‹ˆλ‹€. μ™ΈλΆ€ ν•¨μˆ˜μ˜ 싀행이 λλ‚˜λ”λΌλ„ μ™ΈλΆ€ ν•¨μˆ˜ μ•ˆμ˜ λ³€μˆ˜κ°€ λ©”λͺ¨λ¦¬μ— μ €μž₯λ˜μ–΄ 값을 κΈ°μ–΅ν•˜κ³  μžˆμŠ΅λ‹ˆλ‹€. μ΄λŸ¬ν•œ νŠΉμ§•μœΌλ‘œ ν΄λ‘œμ € λͺ¨λ“ˆ νŒ¨ν„΄μ„ κ΅¬ν˜„ν•  수 μžˆμŠ΅λ‹ˆλ‹€.


ν΄λ‘œμ € λͺ¨λ“ˆ νŒ¨ν„΄μ— λŒ€ν•΄μ„œ μ„€λͺ…ν•΄ λ³΄μ„Έμš”.

ν΄λ‘œμ €μ—μ„œ λ‚΄λΆ€ ν•¨μˆ˜λ₯Ό ν•˜λ‚˜λ§Œ λ¦¬ν„΄ν•˜λŠ” 것이 μ•„λ‹ˆλΌ, 객체에 μ—¬λŸ¬κ°œμ˜ λ‚΄λΆ€ ν•¨μˆ˜λ₯Ό λ¦¬ν„΄ν•˜λ„λ‘ λ§Œλ“  κ²ƒμž…λ‹ˆλ‹€. μ™ΈλΆ€ ν•¨μˆ˜μ— μžˆλŠ” value λ³€μˆ˜λŠ” μŠ€μ½”ν”„ κ·œμΉ™μ— μ˜ν•΄ 값을 μˆ˜μ •ν•˜κ±°λ‚˜ μƒˆλ‘­κ²Œ ν• λ‹Ήν•  수 μ—†μŠ΅λ‹ˆλ‹€. μ •λ³΄μ˜ 접근을 μ œν•œν•˜λŠ” μΊ‘μŠν™”μ˜ νŠΉμ§•μ„ 가지고 μžˆμŠ΅λ‹ˆλ‹€. ν΄λ‘œμ €λ₯Ό 톡해 λΆˆν•„μš”ν•œ μ „μ—­ λ³€μˆ˜μ˜ μ‚¬μš©μ„ 쀄이고 μ•ˆμ „ν•˜κ²Œ 값을 λ³΄ν˜Έν•  수 μžˆμŠ΅λ‹ˆλ‹€. λ˜ν•œ counterA와 counterB의 valueλŠ” μ„œλ‘œμ—κ²Œ 영ν–₯을 주지 μ•ŠμŠ΅λ‹ˆλ‹€. makeCounterλ₯Ό μ™„μ „νžˆ λ…λ¦½λœ ν˜•νƒœλ‘œ μž¬μ‚¬μš©ν•  수 μžˆλŠ” κ²ƒμž…λ‹ˆλ‹€.

const makeCounter = () => {
	let value = 0

	return {
		increase: () => {
			value = value + 1
		},
		decrease: () => {
			value = value - 1
		},
		getValue: () => {
			getValue: () => value
		}
	}
}

const counterA = makeCounter()
const counterB = makeCounter()

ν΄λ‘œμ €λ₯Ό μ‚¬μš©ν–ˆμ„ λ•Œ, 단점을 μ„€λͺ…ν•  수 μžˆλ‚˜μš”?

μ™ΈλΆ€ ν•¨μˆ˜ μŠ€μ½”ν”„κ°€ λ‚΄λΆ€ ν•¨μˆ˜μ— μ˜ν•΄ μ–Έμ œλ“ μ§€ 참쑰될 수 있기 λ•Œλ¬Έμ—, ν΄λ‘œμ € νŒ¨ν„΄μ€ λ©”λͺ¨λ¦¬ 상에 λ‚¨κ²Œ λ©λ‹ˆλ‹€. μ΄λŠ” 일반 ν•¨μˆ˜μ˜€λ‹€λ‹€λ©΄ μ‹€ν–‰ μ’…λ£Œ ν›„ μžλ°”μŠ€ν¬λ¦½νŠΈ λ©”λͺ¨λ¦¬ 관리에 μ˜ν•΄ 가비지 μ»¬λ ‰μ…˜μ΄ λ˜μ—ˆμ„ 객체가 λ‚¨μ•„μžˆκ²Œ λ˜λŠ” κ²ƒμž…λ‹ˆλ‹€. λ”°λΌμ„œ ν΄λ‘œμ €λ₯Ό λ‚¨λ°œν•  경우 퍼포먼슀 μ €ν•˜κ°€ λ°œμƒν•  수 μžˆλ‹€κ³  μ•Œκ³  μžˆμŠ΅λ‹ˆλ‹€.


ν΄λ‘œμ €μ˜ μ˜ˆμ‹œλ₯Ό μž‘μ„±ν•  수 μžˆλ‚˜μš”?

λ„€, 예λ₯Ό λ“€μ–΄ λ‹€μŒκ³Ό 같이 x와 y의 합을 κ΅¬ν•˜λŠ” ν•¨μˆ˜κ°€ μžˆλ‹€κ³  ν•  λ•Œ, λ‹€μŒκ³Ό 같이 μž‘μ„±ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

let add = function(x) {
	let sum = function(y) {
		return x + y
	}
	return sum
}

ν•¨μˆ˜ ν‘œν˜„μ‹μœΌλ‘œ μ„ μ–Έλœ add ν•¨μˆ˜λŠ” xλ₯Ό λ§€κ°œλ³€μˆ˜λ‘œ ν•˜λ©°, λ‚΄λΆ€ ν•¨μˆ˜ sum을 λ°˜ν™˜ν•˜κ³  μžˆμŠ΅λ‹ˆλ‹€. μ—¬κΈ°μ„œ λ°˜ν™˜ν•˜λŠ” ν•¨μˆ˜μΈ sum은 μ™ΈλΆ€ ν•¨μˆ˜μΈ add의 λ§€κ°œλ³€μˆ˜ x에 μ ‘κ·Όν•  수 μžˆμœΌλ―€λ‘œ ν΄λ‘œμ € ν•¨μˆ˜μž…λ‹ˆλ‹€.

let addOne = add(1)
addOne(5) // 6

addOne ν•¨μˆ˜μ— μ „λ‹¬μΈμžλ‘œ 1을 λ°›λŠ” addν•¨μˆ˜λ₯Ό ν• λ‹Ήν•˜λ©΄, addOne은 ν•¨μˆ˜ κ·Έ 자체λ₯Ό μž¬ν• λ‹Ήν•˜κΈ° μ „κΉŒμ§€λŠ” μ™ΈλΆ€ λ³€μˆ˜x인 1에 μ ‘κ·Όν•  수 μ—†κΈ° λ•Œλ¬Έμ— μΊ‘μŠν™”λ₯Ό ν•  수 μžˆλŠ” κ²ƒμž…λ‹ˆλ‹€.


μ’€ 더 μ‹€μš©μ μΈ μ˜ˆμ‹œκ°€ 있으면 μ’‹κ² μŠ΅λ‹ˆλ‹€.

ν΄λ‘œμ €κ°€ μœ μš©ν•˜κ²Œ μ‚¬μš©λ˜λŠ” μ˜ˆλŠ” ν˜„μž¬ μƒνƒœλ₯Ό κΈ°μ–΅ν•˜κ³  λ³€κ²½λœ μ΅œμ‹  μƒνƒœλ₯Ό μœ μ§€ν•˜λŠ” μƒν™©μž…λ‹ˆλ‹€. 예λ₯Ό λ“€λ©΄ toggle λ²„νŠΌμ„ κ΅¬ν˜„ν•  λ•Œ, isShowλΌλŠ” ν•¨μˆ˜κ°€ μžˆλ‹€κ³  κ°€μ •ν•œλ‹€λ©΄ λ‹€μŒκ³Ό 같이 μ μš©ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

const element = document.querySelector('.element')

let toggleHandler = function(element) {
	let isShow = false
	return function() {
		element.style.display = isShow ? 'block' : 'none'
		isShow = !isShow
	}
}

toggleBtn.onclick = toggleHandler

λ‹€λ₯Έ μ˜ˆμ‹œλ‘œ, ν΄λ‘œμ €λ₯Ό μ΄μš©ν•΄ HTML νƒœκ·Έλ₯Ό μƒμ„±ν•˜λŠ” κ²½μš°μž…λ‹ˆλ‹€. tagλ₯Ό μ™ΈλΆ€ ν•¨μˆ˜ λ³€μˆ˜μ— 담아두어 μŠ€μ½”ν”„ μ•ˆμ— 가두어 λ‘” 채 μž¬μ‚¬μš©μ„ ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

const tagMaker = tag => content => `<${tag}>${content}</${tag}>`

const divMaker = tagMaker('div')
divMaker('hello') // <div>hello<div>
divMaker('code') // <div>code</div>

const anchorMaker = tagMaker('a')
anchorMaker('go') // <a>go</a>
anchorMaker('class') // <a>class</a>

λ‚˜λ¦„ κ°„κ²°ν•˜κ²Œ 핡심을 μ „λ‹¬ν•˜λ©΄μ„œ λ‚΄μš©μ΄ 비어보이지 μ•Šλ„λ‘ ν–ˆλŠ”λ°, ν πŸ€”Β λ©΄μ ‘λ•Œ μ€€λΉ„ν•œ λ‚΄μš©μ„ μžμ—°μŠ€λŸ½κ²Œ μ–˜κΈ°ν•  수 μžˆμ„κΉŒ? μœ„ counter μ˜ˆμ‹œλŠ” ν•™μŠ΅μ— λ‚˜μ˜¨ μ˜ˆμ‹œμ΄κΈ°λ„ ν•˜κ³  ν΄λ‘œμ €λ₯Ό μ„€λͺ…ν•  λ•Œ 자주 μ†Œκ°œλ˜λŠ” μ˜ˆμ‹œλΌκ³  ν•œλ‹€.

μ •λ¦¬ν•˜λ©΄μ„œ 쑰금 더 곡뢀해보고 싢은 λ‚΄μš©μ€ ν΄λ‘œμ €λ‘œ κ΅¬ν˜„ν•œ 컀링과 IIFE(μ¦‰μ‹œμ‹€ν–‰ν•¨μˆ˜ν˜ΈμΆœ)을 ν™œμš©κ³Ό μžλ°”μŠ€ν¬λ¦½νŠΈμ˜ 은닉화에 λŒ€ν•΄μ„œλ‹€.

πŸ‘‰ λ¦¬μ•‘νŠΈμ—μ„œ IIFE μ‚¬μš©ν•˜κΈ° | 2022.1.5 μž‘μ„±

좜처

ν΄λ‘œμ € | μ½”λ“œμŠ€ν…Œμ΄μΈ  μœ μ–΄ν΄λž˜μŠ€
ν΄λ‘œμ € | MDN
ν΄λ‘œμ €, 그리고 μΊ‘μŠν™”μ™€ 은닉화 | NHN Cloud Meetup!

post-custom-banner

1개의 λŒ“κΈ€

comment-user-thumbnail
2024λ…„ 1μ›” 24일

ν΄λ‘œμ € λ©΄μ ‘ 닡변쀑에 μ΅œκ³ μΈκ²ƒκ°™μ•„μš” >< b

λ‹΅κΈ€ 달기