[TIL] ν΄λ‘œμ € 😧

κΉ€μœ€ν˜œΒ·2022λ…„ 11μ›” 8일
0

ν΄λ‘œμ €(Closure)

  • μ™ΈλΆ€ν•¨μˆ˜μ˜ λ³€μˆ˜μ— μ ‘κ·Όν•  수 μžˆλŠ” λ‚΄λΆ€ν•¨μˆ˜
  • ν•¨μˆ˜μ™€ ν•¨μˆ˜κ°€ μ„ μ–Έλœ μ–΄νœ˜μ  ν™˜κ²½μ˜ μ‘°ν•© (μ–΄νœ˜μ (lexical) ν™˜κ²½; λ³€μˆ˜ 및 ν•¨μˆ˜μ„ μ–Έμ˜ ν˜•νƒœ)

ν•¨μˆ˜λ₯Ό λ¦¬ν„΄ν•˜λŠ” ν•¨μˆ˜

// ν™”μ‚΄ν‘œ ν•¨μˆ˜(μ€‘κ΄„ν˜Έλ„ μ—†λ‹€!)
const add = (x, y) => x + y;
add(1, 2); // 3;


// ν™”μ‚΄ν‘œ ν•¨μˆ˜λ‘œ ν‘œν˜„ν•œ ν•¨μˆ˜ μ•ˆμ˜ ν•¨μˆ˜
const adder = x => y => x + y;
adder(5); // y => x + y; // μ΄λ•Œ x에 5κ°€ λœ¨μ§„ μ•Šμ§€λ§Œ 5κ°€ μž…λ ₯된 μƒνƒœ
adder(5)(5); // 10; // ν•¨μˆ˜λ₯Ό 2번 좜λ ₯ν•œλ‹€.


// ν•¨μˆ˜ ν‘œν˜„μ‹μœΌλ‘œ 
const adder = function(x) {
	return function(y) {
    	return x + y;
    }
}

typeof adder(2) // 'function'
typeof adder(2)(2) // 'number'
  • ν΄λ‘œμ € ν•¨μˆ˜ & μŠ€μ½”ν”„
    - function(x); μ™ΈλΆ€ν•¨μˆ˜, function(y); λ‚΄λΆ€ν•¨μˆ˜
    -> λ‚΄λΆ€ν•¨μˆ˜λŠ” μ™ΈλΆ€ν•¨μˆ˜μ˜ λ³€μˆ˜μ— μ ‘κ·Ό κ°€λŠ₯ν•˜λ‹€.


ν΄λ‘œμ € ν•¨μˆ˜μ˜ ν™œμš©

  • 일반 ν•¨μˆ˜λŠ” ν•¨μˆ˜μ‹€ν–‰ ν›„ ν•¨μˆ˜ λ‚΄λΆ€μ—μ„œ μ„ μ–Έν•œ λ³€μˆ˜λ₯Ό μ‚¬μš©ν•  수 μ—†λ‹€.
function value0 () {
    let value = 0; 
	return value; 
}

console.log(value); // Uncaught ReferenceError: value is not defined
value0 (); //0   

- ν΄λ‘œμ € ν•¨μˆ˜λŠ” μ™ΈλΆ€ ν•¨μˆ˜ μ‹€ν–‰ ν›„ 내뢀에 μ„ μ–Έλœ λ³€μˆ˜κ°€ λ©”λͺ¨λ¦¬μ— μ €μž₯λ˜μ–΄ μ‚¬μš© κ°€λŠ₯ν•˜λ‹€.
// μ˜ˆμ‹œ 1)
const adder = function(x) {
	return function(y) {
    	return x + y;
    }
}

const add5 = adder(5); // μ „λ‹¬μΈμž 5λ₯Ό λ§€κ°œλ³€μˆ˜ x에 담은 μƒνƒœ
add5(1) // 6


// μ˜ˆμ‹œ 2)
// 2-1) ν™”μ‚΄ν‘œ ν•¨μˆ˜
const tagMaker = tag => content => `<${tag}>${content}</${tag}>`

// 2-2) ν•¨μˆ˜ ν‘œν˜„μ‹
const tagMaker = function(tag) {
	return function(content) {
    	return `<${tag}>${content}</${tag}>`
    }
}

const divMaker = tagMaker('div'); // 
console.log(divMaker); Ζ’ (content) {
    						return `<${tag}>${content}</${tag}>`
    					}
divMaker('hello'); // <div>hello</div>

** ν΄λ‘œμ €λŠ” νŠΉμ • 데이터(tag)λ₯Ό μŠ€μ½”ν”„ μ•ˆ(function(tag))에 κ°€λ‘” μ±„λ‘œ 계속 μ‚¬μš©ν•  수 있게 ν•œλ‹€.

ν΄λ‘œμ € λͺ¨λ“ˆνŒ¨ν„΄

// ν™”μ‚΄ν‘œ ν•¨μˆ˜
const makeCounter = () => {
	let value = 0;
    
    return {
    	increase: () => {
        	value = value + 1
        },
        decrease: () => {
        	value = value - 1
        },
        getValue: () => value
    }
}

const counter1 = makeCounter();
counter1 = {increase: Ζ’, decrease: Ζ’, getValue: Ζ’};
typeof counter1; // 'object'



// ν•¨μˆ˜ ν‘œν˜„μ‹μœΌλ‘œ λ§Œλ“€μ–΄λ³΄κΈ°(μ‹€νŒ¨)
// const makeCounter = function () {
// 	let value = 0;
//     return { 
//     	const increase: funtion () {
//         	value = value + 1;
//         const decrease: funtion () {
//         	value = value - 1;
//         const getValue: getValue () {
//         	value;
//            }
//          }
//        }
//     }
// }
  • makeCounterν•¨μˆ˜λ₯Ό 바꾸지 μ•Šκ³  value 값을 μž¬ν• λ‹Ήν•  수 μ—†λ‹€.
    -> [μΊ‘μŠν™”; 정보 μ ‘κ·Ό μ œν•œ] μ™ΈλΆ€μŠ€μ½”ν”„μ—μ„œ λ‚΄λΆ€μŠ€μ½”ν”„μ˜ λ³€μˆ˜μ— μ ‘κ·Όν•  수 μ—†κΈ° λ•Œλ¬Έ
    => makeCounter ν•¨μˆ˜ μŠ€μ½”ν”„λ‘œ valueλ₯Ό 감싸지 μ•ŠμœΌλ©΄ value값은 μ „μ—­λ³€μˆ˜κ°€ 됨(side effect 🚫)
  • ν΄λ‘œμ € ν•¨μˆ˜λ₯Ό 톡해 μ „μ—­λ³€μˆ˜ μ‚¬μš©μ„ 쀄이고, μŠ€μ½”ν”„λ₯Ό 톡해 값을 μ•ˆμ „ν•˜κ²Œ λ‹€λ£° 수 있음

  • λ‚΄λΆ€ν•¨μˆ˜λ₯Ό μ΄μš©ν•œ 간접적인 value κ°’μ˜ μž¬ν• λ‹Ή(λͺ¨λ“ˆν™”)
const counter1 = makeCounter();
counter1.increase(); // 0 + 1 = 1
counter1.increase(); // 1 + 1 = 2
counter1.decrease(); // 2 - 1 = 1
counter1.getValue(); // 1;


const counter2 = makeCounter();
counter2.increase(); // 0 + 1 = 1
counter2.decrease(); // 1 - 1 = 0
counter2.decrease(); // 0 - 1 = -1
counter2.getValue(); // -1;

counter1κ³Ό counter2μ—μ„œμ˜ value값은 각각 보쑴됨

profile
λ³Έμ§ˆμ—λŠ” 일치λ₯Ό, λΉ„λ³Έμ§ˆμ—λŠ” κ΄€μš©μ„, 이 λͺ¨λ“  것에 μ‚¬λž‘μ„

0개의 λŒ“κΈ€