์ค๋์ ์๋ฐ์คํฌ๋ฆฝํธ์์ ์ค์ํ ๊ฐ๋ ์ค ํ๋์ธ ํด๋ก์ ์ ๋ํด ์์๋ณด๊ฒ ์ต๋๋ค. ํด๋ก์ ๋ ์๋ฐ์คํฌ๋ฆฝํธ์ ๊ฐ๋ ฅํ ๊ธฐ๋ฅ ์ค ํ๋์ ๋๋ค. ์ด ๊ธ์์๋ ํด๋ก์ ์ ๊ธฐ๋ณธ ๊ฐ๋ ๋ถํฐ ์ค์ ์์ ๊น์ง ์์ธํ ๋ค๋ฃฐ ์์ ์ด๋, ๋๊น์ง ํจ๊ป ํด์ฃผ์ธ์!
โฃ ๋ชฉ์ฐจ
- ํด๋ก์ ์ ๊ธฐ๋ณธ ๊ฐ๋ ์ดํดํ๊ธฐ๐ง
- ํด๋ก์ ์ ์ฃผ์ ํน์ง๊ณผ ์ฅ์ ๐
- ์ค์ ์์ ๋ก ๋ฐฐ์ฐ๋ ํด๋ก์ ํ์ฉ๋ฒ๐ป
- ํด๋ก์ ์ฌ์ฉ ์ ์ฃผ์ํ ์ โ ๏ธ

01. ํด๋ก์ ์ ๊ธฐ๋ณธ ๊ฐ๋ ์ดํดํ๊ธฐ๐ง
์๋ฐ์คํฌ๋ฆฝํธ์ ์ค์ฝํ์ ํด๋ก์ ์ ๊ด๊ณ
ํด๋ก์ ๋ฅผ ์ดํดํ๋ ค๋ฉด ๋จผ์ ์๋ฐ์คํฌ๋ฆฝํธ์ ์ค์ฝํ(scope) ๊ฐ๋ ์ ์์์ผ ํฉ๋๋ค. ์ค์ฝํ๋ ๋ณ์์ ์ ํจ ๋ฒ์๋ฅผ ์๋ฏธํ๋ฉฐ, ์๋ฐ์คํฌ๋ฆฝํธ๋ ํจ์ ์ค์ฝํ์ ๋ธ๋ก ์ค์ฝํ๋ฅผ ์ง์ํฉ๋๋ค.
์๋ฐ์คํฌ๋ฆฝํธ ์ค์ฝํ์ ์กฐ๊ธ ๋ ์์ธํ ์๊ณ ์ถ๋ค๋ฉด ์๋ ํฌ์คํ ์ ์ฐธ๊ณ ํด ์ฃผ์ธ์๐
[Javascript]์๋ฐ์คํฌ๋ฆฝํธ ์ค์ฝํ ์๋ฒฝ ๊ฐ์ด๋: ๊ธฐ์ด๋ถํฐ ๊ณ ๊ธ๊น์ง
์๋ฐ์คํฌ๋ฆฝํธ๋ฅผ ๋ค๋ฃจ๋ ๋ฐ ์์ด์ '์ค์ฝํ'๋ ๋งค์ฐ ์ค์ํ ๊ฐ๋ ์ ๋๋ค. ์ค์ฝํ๋ฅผ ์ดํดํ๋ฉด ์ฝ๋์ ๊ฐ๋ ์ฑ์ ๋์ด๊ณ , ๋ฒ๊ทธ๋ฅผ ์ค์ด๋ ๋ฐ ํฐ ๋์์ด ๋ฉ๋๋ค. ์ด๋ฒ ๊ธ์์๋ ์๋ฐ์คํฌ๋ฆฝํธ ์ค์ฝํ์
creativevista.tistory.com
ํด๋ก์ ์ ๋์ ์๋ฆฌ
ํด๋ก์ ๋ ํจ์๊ฐ ์ ์ธ๋ ๋์ ์ค์ฝํ๋ฅผ ๊ธฐ์ตํ๋ ๊ธฐ๋ฅ์ ๋งํฉ๋๋ค. ์ฆ, ํจ์๊ฐ ์คํ๋ ์ดํ์๋ ํด๋ก์ ๋ ๊ทธ ํจ์๊ฐ ์ ์ธ๋ ํ๊ฒฝ์ ์ฐธ์กฐํ ์ ์์ต๋๋ค.
function outerFunction() {
let outerVariable = 'I am outside!';
function innerFunction() {
console.log(outerVariable);
}
return innerFunction;
}
const innerFunc = outerFunction();
innerFunc(); // 'I am outside!' ์ถ๋ ฅ
์ ์ฝ๋์์ innerFunction์ outerVariable์ ์ฐธ์กฐํ ์ ์์ต๋๋ค. ์ด๊ฒ์ด ํด๋ก์ ์ ๊ธฐ๋ณธ ๋์ ๋ฐฉ์์ ๋๋ค.
02. ํด๋ก์ ์ ์ฃผ์ ํน์ง๊ณผ ์ฅ์ ๐
๋ฐ์ดํฐ ์๋ (Data Encapsulation)
ํด๋ก์ ๋ฅผ ์ฌ์ฉํ๋ฉด ํจ์ ๋ด๋ถ์ ๋ณ์๋ฅผ ์ธ๋ถ์์ ์ง์ ์ ๊ทผํ ์ ์๋๋ก ํ ์ ์์ต๋๋ค. ์ด๋ ๋ฐ์ดํฐ ์๋์ ํตํด ์ฝ๋์ ๋ณด์์ฑ๊ณผ ์ ์ง๋ณด์์ฑ์ ๋์ฌ์ค๋๋ค.
function createCounter() {
let count = 0;
return function() {
count++;
return count;
}
}
const counter = createCounter();
console.log(counter()); // 1
console.log(counter()); // 2
console.log(counter()); // 3
๋ชจ๋ํ์ ์ฝ๋ ์ฌ์ฌ์ฉ์ฑ
ํด๋ก์ ๋ ๋ชจ๋ํ๋ ์ฝ๋๋ฅผ ์์ฑํ๊ณ ์ฌ์ฌ์ฉ์ฑ์ ๋์ด๋ ๋ฐ ์ ์ฉํฉ๋๋ค. ํจ์ ํฉํ ๋ฆฌ๋ ์ฆ์ ์คํ ํจ์ ํํ์(IIFE) ๋ฑ์ ํ์ฉํ์ฌ ๋ชจ๋ ํจํด์ ๊ตฌํํ ์ ์์ต๋๋ค.
๋ฐ์ดํฐ ์บ์ฑ (Data Caching)
ํด๋ก์ ๋ฅผ ์ด์ฉํด ๊ณ์ฐ๋ ๊ฐ์ ์ ์ฅํด ๋๊ณ , ๊ฐ์ ๊ณ์ฐ์ ๋ฐ๋ณต์ ์ผ๋ก ํ์ง ์๋๋ก ํ ์ ์์ต๋๋ค. ์ด๋ฅผ ํตํด ์ฑ๋ฅ์ ์ต์ ํํ ์ ์์ต๋๋ค.
function createCachedFunction() {
const cache = {};
return function(key, computeFunc) {
if (!cache[key]) {
cache[key] = computeFunc();
}
return cache[key];
}
}
const cachedCompute = createCachedFunction();
const result1 = cachedCompute('result', () => {
console.log('Computing result...');
return 42;
});
const result2 = cachedCompute('result', () => {
console.log('Computing result...');
return 42;
});
console.log(result1); // 42, 'Computing result...' ์ถ๋ ฅ
console.log(result2); // 42, 'Computing result...' ์ถ๋ ฅ๋์ง ์์
๋ฐ๋ณต์ ์ธ ๋ฐ์ดํฐ ์บ์ฑ ํ์ฉ
๋ฐ์ดํฐ ์บ์ฑ์ ํด๋ก์ ๋ก ๊ตฌํํ๋ฉด ๋ฐ๋ณต์ ์ธ ์ฐ์ฐ์์ ์ฑ๋ฅ์ ํฌ๊ฒ ํฅ์ํ ์ ์์ต๋๋ค. ํนํ, ๋์ผํ ์ฐ์ฐ์ด ๋ฐ๋ณต์ ์ผ๋ก ์ํ๋๋ ์ํฉ์์ ์ ์ฉํฉ๋๋ค.
function createFibonacci() {
const cache = {};
function fibonacci(n) {
if (n in cache) {
return cache[n];
}
if (n <= 1) {
return n;
} else {
const result = fibonacci(n - 1) + fibonacci(n - 2);
cache[n] = result;
return result;
}
}
return fibonacci;
}
const fib = createFibonacci();
console.log(fib(10)); // 55
console.log(fib(20)); // 6765
์ ์์ ์์๋ ํผ๋ณด๋์น ์์ด์ ๊ณ์ฐํ ๋ ํด๋ก์ ๋ฅผ ์ด์ฉํด ์ด๋ฏธ ๊ณ์ฐ๋ ๊ฐ์ ์บ์ฑํจ์ผ๋ก์จ ์ฑ๋ฅ์ ์ต์ ํํ๊ณ ์์ต๋๋ค.
03. ์ค์ ์์ ๋ก ๋ฐฐ์ฐ๋ ํด๋ก์ ํ์ฉ๋ฒ ๐ป
ํจ์ ํฉํ ๋ฆฌ (Function Factory)
ํจ์ ํฉํ ๋ฆฌ๋ ํด๋ก์ ๋ฅผ ํ์ฉํ์ฌ ๋์ ์ผ๋ก ํจ์๋ฅผ ์์ฑํ๋ ๊ธฐ๋ฒ์ ๋๋ค.
function multiplier(factor) {
return function(number) {
return number * factor;
}
}
const double = multiplier(2);
console.log(double(5)); // 10
์ฝ๋ฐฑ ํจ์ (Callback Function)
์ฝ๋ฐฑ ํจ์์์๋ ํด๋ก์ ๋ฅผ ์์ฃผ ์ฌ์ฉํฉ๋๋ค. ์ด๋ฒคํธ ํธ๋ค๋ฌ๋ ๋น๋๊ธฐ ์์ ์์ ์ ์ฉํ๊ฒ ํ์ฉ๋ฉ๋๋ค.
function fetchData(url) {
fetch(url)
.then(response => response.json())
.then(data => {
console.log(data);
});
}
์ด๋ฒคํธ ํธ๋ค๋ฌ (Event Handler)
์ด๋ฒคํธ ํธ๋ค๋ฌ์์๋ ํด๋ก์ ๋ฅผ ์ฌ์ฉํ์ฌ ์ํ๋ฅผ ์ ์งํ ์ ์์ต๋๋ค.
function setupEventHandlers() {
let count = 0;
document.getElementById('myButton').addEventListener('click', function() {
count++;
console.log(`Button clicked ${count} times`);
});
}
04. ํด๋ก์ ์ฌ์ฉ ์ ์ฃผ์ํ ์ โ ๏ธ
1. ๋ฉ๋ชจ๋ฆฌ ๋์
ํด๋ก์ ๋ ํจ์๊ฐ ์ธ๋ถ ํจ์์ ๋ณ์์ ์ ๊ทผํ ์ ์๊ฒ ํด ์ฃผ๊ธฐ ๋๋ฌธ์, ํ์ ์๋ ํด๋ก์ ๋ฅผ ์ฌ์ฉํ๋ฉด ๋ฉ๋ชจ๋ฆฌ ๋์๊ฐ ๋ฐ์ํ ์ ์์ต๋๋ค. ์ด๋ ํนํ ์ค๋ ์คํ๋๋ ์ ํ๋ฆฌ์ผ์ด์ ์์ ๋ฌธ์ ๋ฅผ ์ผ์ผํฌ ์ ์์ต๋๋ค.
์ฃผ์์ฌํญ:
- ํ์ ์๋ ํด๋ก์ ๋ฅผ ์์ฑํ์ง ์๋๋ก ์ฃผ์ํฉ๋๋ค.
- ํด๋ก์ ๊ฐ ๋ ์ด์ ํ์ํ์ง ์์ ๋ ์ฐธ์กฐ๋ฅผ ํด์ ํ์ฌ ๊ฐ๋น์ง ์ปฌ๋ ์ ์ด ์ด๋ฃจ์ด์ง๋๋ก ํฉ๋๋ค.
2. ์ฑ๋ฅ ์ ํ
ํด๋ก์ ๋ ํจ์๊ฐ ์ ์ธ๋ ๋๋ง๋ค ์๋ก์ด ๊ฐ์ฒด๋ฅผ ์์ฑํ๊ธฐ ๋๋ฌธ์, ๋ง์ ํด๋ก์ ๋ฅผ ์์ฑํ๋ฉด ์ฑ๋ฅ์ด ์ ํ๋ ์ ์์ต๋๋ค.
์ฃผ์์ฌํญ:
- ํด๋ก์ ๊ฐ ์ ๋ง ํ์ํ ๊ฒฝ์ฐ์๋ง ์ฌ์ฉํฉ๋๋ค.
- ๋ฐ๋ณต๋ฌธ ์์์ ํด๋ก์ ๋ฅผ ์์ฑํ๋ ๊ฒฝ์ฐ ์ฃผ์ํฉ๋๋ค.
3. ๋ณ์์ ์๋ชป๋ ์ฐธ์กฐ
ํด๋ก์ ๋ ์ธ๋ถ ํจ์์ ๋ณ์๋ฅผ ์ฐธ์กฐํ ์ ์์ง๋ง, ์์์น ๋ชปํ ๊ฐ์ด ์ฐธ์กฐ๋ ์ ์์ต๋๋ค. ํนํ ๋ฐ๋ณต๋ฌธ์์ ํด๋ก์ ๋ฅผ ์ฌ์ฉํ ๋ ์ฃผ์ํด์ผ ํฉ๋๋ค.
์์:
for (var i = 0; i < 5; i++) {
setTimeout(function() {
console.log(i); // ๋ชจ๋ ํด๋ก์ ๊ฐ ๋ง์ง๋ง ๊ฐ์ธ 5๋ฅผ ์ถ๋ ฅํจ
}, 1000);
}
ํด๊ฒฐ์ฑ :
- let ํค์๋๋ฅผ ์ฌ์ฉํ์ฌ ๋ธ๋ก ์ค์ฝํ ๋ณ์๋ฅผ ์์ฑํ๊ฑฐ๋, ์ฆ์ ์คํ ํจ์(IIFE)๋ฅผ ์ฌ์ฉํฉ๋๋ค.
for (let i = 0; i < 5; i++) {
setTimeout(function() {
console.log(i); // ๊ฐ ํด๋ก์ ๊ฐ ๊ณ ์ ํ ๊ฐ์ ์ถ๋ ฅํจ
}, 1000);
}
4. ์ฝ๋ ๊ฐ๋ ์ฑ ์ ํ
ํด๋ก์ ๋ฅผ ๊ณผ๋ํ๊ฒ ์ฌ์ฉํ๋ฉด ์ฝ๋๊ฐ ๋ณต์กํด์ง๊ณ ์ดํดํ๊ธฐ ์ด๋ ค์์ง ์ ์์ต๋๋ค. ์ด๋ ์ ์ง๋ณด์์ ์ด๋ ค์์ ์ค ์ ์์ต๋๋ค.
์ฃผ์์ฌํญ:
- ํด๋ก์ ๋ฅผ ์ฌ์ฉํ๋ ์ด์ ๋ฅผ ๋ช ํํ ํ๊ณ , ์ฃผ์์ ํตํด ์ค๋ช ์ ์ถ๊ฐํฉ๋๋ค.
- ํด๋ก์ ๋ฅผ ์ ์ ํ ์บก์ํํ์ฌ ์ฌ์ฉํฉ๋๋ค.
5. ๋น๋๊ธฐ ํจ์์์ ์ฌ์ฉ
๋น๋๊ธฐ ํจ์์ ํด๋ก์ ๋ฅผ ํจ๊ป ์ฌ์ฉํ ๋ ์ฃผ์ํด์ผ ํฉ๋๋ค. ํด๋ก์ ๊ฐ ๋น๋๊ธฐ ํจ์ ๋ด๋ถ์์ ์ฌ์ฉ๋ ๋, ์๋ํ ์์ ์ ์ฌ๋ฐ๋ฅธ ๊ฐ์ ์ฐธ์กฐํ๋์ง ํ์ธํด์ผ ํฉ๋๋ค.
์์:
function fetchData(url) {
var data = "old data";
setTimeout(function() {
console.log(data); // "old data"๊ฐ ์ถ๋ ฅ๋จ
}, 1000);
// ๋น๋๊ธฐ ์์
์ด ์๋ฃ๋ ํ ๋ฐ์ดํฐ๊ฐ ๋ณ๊ฒฝ๋จ
data = "new data";
}
fetchData('example.com');
ํด๊ฒฐ์ฑ :
- ํด๋ก์ ๋ด๋ถ์์ ํ์ํ ๋ฐ์ดํฐ๋ฅผ ๋ฏธ๋ฆฌ ์ ์ฅํ๊ฑฐ๋, ๋น๋๊ธฐ ์์ ์ด ์๋ฃ๋ ํ์ ํด๋ก์ ๋ฅผ ์คํํฉ๋๋ค.
function fetchData(url) {
var data = "old data";
setTimeout((function(dataCopy) {
return function() {
console.log(dataCopy); // "old data"๊ฐ ์ถ๋ ฅ๋จ
};
})(data), 1000);
data = "new data";
}
fetchData('example.com');
์ด์ ๊ฐ์ ์ฃผ์์ฌํญ์ ๋ช ์ฌํ๋ฉด ํด๋ก์ ๋ฅผ ๋์ฑ ์์ ํ๊ณ ํจ๊ณผ์ ์ผ๋ก ์ฌ์ฉํ ์ ์์ต๋๋ค.