본문 바로가기
JavaScript | 자바스크립트

클로저 - closure

by Pig_CoLa 2020. 7. 15.
SMALL

클로저

클로저란 외부함수의 변수에 접근할수 있는 내부함수.

또는 그러한 패턴 자체를 클로저, 클로저 패턴 이라고 한다.

전에 스코프를 기술할때에 스코프 외부에서 스코프 내부로는 접근할 수 없다고 했지만

이를 가능하게 해주는것이 클로저, 클로저 패턴 이라고 할수 있다.

function hi() {
    let text = '안녕하세요'

    function hello() {
        console.log(text)
    }

    return hello
}

let a = hi()

console.log(text) // 참조오류 -> text가 정의되지 않음
console.log(a) // hello함수에 해당하는 내용을 보여줌
a() // '안녕하세요'

이렇게 global scope에서 함수 hi가 갖고있는

function scope또는 block scope에 접근할 수 있게되는 것이다.

또한 이러한 패턴의 특징을 활용하여 커링을 사용할 수 있다.

클로저 패턴으로 커링하기

커링은 함수 하나가 여러개의 인자를 받아야 할때 하나의 인자를 미리 바인딩 하게 만드는 것을 뜻한다.

커링을 사용하게 되면 '함수를 만드는 함수'를 만들수 있고 만들어진 함수를 재활용 할 수 있다.

(커링또한 그런한 방법, 패턴을 뜻한다. 추후에 bind를 사용한 커링도 기술할 예정.)

// case 1
function sumAandB (a, b) { // 단순히 전달인자 두개를 받아 서로 더해주는 함수
    return a + b
}

sumAandB(10,26) // 36
sumAandB(33,77) // 110
sumAandB(10, 1) // 11
// case 2
function makeSumAandAny (a) { // 아래의 익명함수를 return
    return (b) => (a + b) // 기존에 전달인자로 받았던 a를 입력받은 b에 더한다.
}

let sum10 = makeSumAandAny(10)
// 함수를 재활용 할 수 있다.

sum10(3) // 13
sum10(55) // 65
sum10(24) // 34

클로저 패턴으로 변수 감추기 (변수의 값 고정하기)

클로저 패턴을 사용하면 외부에서 접근할 수 없는 변수에 접근이 가능하다고 했다.

그건 반대로, 외부에서 의도되지 않은 조작으로는 접근하지 못하게 하기 위해서는

클로저 패턴을 활용하면 된다는 뜻 이기도 하다.

function makeCounter() {
    let count = 0;
        return { // 값이 함수들인 객체를 return해준다. key값으로 메서드처럼 사용된다.
            getValue: () => (count),
            up: () => {count ++}, // count += 1 또는 count = count + 1 과 같다
            down: () => {count --} // count -= 1 또는 count = count - 1 과 같다
            }
}

let counter1 = makeCounter();
counter1.getValue(); // 0
counter1.up();
counter1.up();
counter1.up();
counter1.getValue(); // 3
counter1.down();
counter1.getValue(); // 2

// 이 방법 역시 재사용이 가능하다.

let counter2 = makeCounter();
counter2.up()
counter2.up()
counter2.down()
counter2.getValue() // 1
counter1.getValue() // 2
// 각각의 값에 영향을 끼치지 않는다.

이 방법은 특정한 값, 특정한 타입 등

오류를 일으킬만한 값으로 변하지 못하게 할 때 매우 크게 기여한다.

let test = (() => {
    let isPass = false
    return {
        state: () => (isPass),
        pass: () => {isPass = true},
        fail: () => {isPass = false}
        })()
// 위는 익명함수를 선언과 동시에 호출하는 IIFE방법을 이용하여 변수test에 호출결과를 할당한 예시다.

test.state() // false
test.pass()
test.state() // true
test.fail()
test.state() // false
// isPass라는 변수는 외부에서 접근할수 없으며
// 오로지 true, false만이 isPass의 값이 될수 있다.

만일 우리가 만든 함수가 예외처리가 올바르지 못해서... 혹은 정말 특수한 상황이라서

특정한 값만을 요구한다면 이러한 방법으로 값을 한정시킬 수 있다.

LIST

'JavaScript | 자바스크립트' 카테고리의 다른 글

DOM - 2  (0) 2020.07.16
DOM - 1  (0) 2020.07.15
스코프 - Scope  (0) 2020.07.14
for ...of문 / for ...in문  (0) 2020.07.14
반복문 - for  (0) 2020.07.13

댓글