λ³Έλ¬Έ λ°”λ‘œκ°€κΈ°
Language/Javascript

[Javascript]μžλ°”μŠ€ν¬λ¦½νŠΈ ν΄λ‘œμ € μ™„λ²½ κ°€μ΄λ“œ: 이해뢀터 μ‹€μ „ μ˜ˆμ œκΉŒμ§€

by YJ Dev 2024. 7. 8.
728x90
λ°˜μ‘ν˜•
SMALL

μ˜€λŠ˜μ€ μžλ°”μŠ€ν¬λ¦½νŠΈμ—μ„œ μ€‘μš”ν•œ κ°œλ… 쀑 ν•˜λ‚˜μΈ ν΄λ‘œμ €μ— λŒ€ν•΄ μ•Œμ•„λ³΄κ² μŠ΅λ‹ˆλ‹€. ν΄λ‘œμ €λŠ” μžλ°”μŠ€ν¬λ¦½νŠΈμ˜ κ°•λ ₯ν•œ κΈ°λŠ₯ 쀑 ν•˜λ‚˜μž…λ‹ˆλ‹€. 이 κΈ€μ—μ„œλŠ” ν΄λ‘œμ €μ˜ κΈ°λ³Έ κ°œλ…λΆ€ν„° μ‹€μ „ μ˜ˆμ œκΉŒμ§€ μžμ„Ένžˆ λ‹€λ£° μ˜ˆμ •μ΄λ‹ˆ, λκΉŒμ§€ ν•¨κ»˜ ν•΄μ£Όμ„Έμš”!

μžλ°”μŠ€ν¬λ¦½νŠΈ ν΄λ‘œμ €


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');

이와 같은 μ£Όμ˜μ‚¬ν•­μ„ λͺ…μ‹¬ν•˜λ©΄ ν΄λ‘œμ €λ₯Ό λ”μš± μ•ˆμ „ν•˜κ³  효과적으둜 μ‚¬μš©ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

728x90
λ°˜μ‘ν˜•