Clousure 클로저 Scope . .

클로저


그동안 개발을 해오면서 당연하게도 알고있던 개념인데도 불구하고 정확하게
알려고 하지 않았다 . 없어도 잘만 개발했으니까 다시 말해서 네이티브 수준 레벨에서
자바스크립트를 강하게 다룰일이 없어서 그랬던것 이기도 하지만
솔직히 이것도 제대로 모른다는게 무척이나 부끄러웠고 그래서 정리 해보고자 한다

function counter(){
    let num = 0;
    return function(){
        num++;
        console.log(num);
    }
}

const count = counter();
count(); // 1
count(); // 2

가장 이해하기 쉬운 예를 골랐다
counter 메서드의 내부의 num 은 지역 변수 인데도 불구하고 아래 호출 결과값은
지역 변수 num 이 계속 증가 하는것을 확인 할 수 있다

메서드 안에 메서드가 바로 핵심이다
counter 메서드의 실행이 끝나고 소멸된 이후에도 리턴받은 내부 익명 함수가
아직 소멸되지 않았기 때문에 num 지역변수의 값이 유지되며 접근이 가능한 것이다

function wrap(execute){
    return execute;
};

var errorExec = wrap(function(){
    throw new Error('Error');
});

console.log(errorExec);  // Function 이 리턴됨
console.log(errorExec()); // Function 을 '사용' 함

위 예제에서

래핑 메서드 errorExec 에 담고 실행 하게되면
래핑 메서드 안에서

wrap 메서드가 파라미터로 받아와서 리턴하는 객체가
메서드이기 때문에 메서드를 리턴하게 되고

두번째 errorExec() 에선 리턴된 메서드를 ()
만나서 리턴받은 메서드를 실행하게 됨으로
Error 가 리턴 된다

이게 가능한 이유도 역시 클로저이다 ..
errorExec 는 한번 리턴하고 결과 없이
사라져야 하지만 내부에서 함수를 리턴 ( 클로저 생성 )

하기 때문에 메모리상에서 사라지지 않고 남아 있어
실행이 가능한 것이다

function wrap(execute){
    return execute;
};

var errorExec = wrap(function(){
    throw new Error('Error');
});

var resultExec = wrap(function(){
    return ('Result');
});

console.log(errorExec && errorExec()); // null
console.log(errorExec && resultExec()); // Result

그럼 위 와같은 환경에서 null, result 를 반환 받으려면 어떻게 해야할까

function wrap(execute){
    return function(){
        try{
            return execute();    
        }catch{
            execute = null;
            return null;
        }
    }
};

console.log(errorExec && errorExec()); // null
console.log(errorExec && resultExec()); // Result

위와같이 wrap 메서드를 변경 해주면

console.log(errorExec && errorExec());
에서 erroExec 는 false 가 아니기 때문에 errorExec
에서 리턴받은 함수를 () 으로 실행한다

에러를 리턴하기 때문에 catch 로 빠지고
catch 로 빠진경우 null 을 리턴하도록 처리

(errorExec && resultExec())
에서 erroExec 는 false 가 아니기 때문에 resultExec
에서 리턴받은 함수를 () 으로 실행한다

래핑된 return ('Result'); 를 만나
Result 를 호출 하여 이 부분은 처리 된다

좋은 웹페이지 즐겨찾기