Javascript Closure

eunji hwang·2020년 8월 15일
0

Javascript

목록 보기
7/8

클로져(Closure)

클로져는 자바스크립트의 함수가 갖는 특징 중 하나의 함수 형태를 말한다.
자바스크립트에서 함수는 1급, number, string과 같이 값으로 취급하게 된다. 즉, 값이될 수 있는 함수는 함수의 인자로서 받거나 리턴할 수 있게 된다. 이것을 활용하여, 특정 함수로만 접근할수 있는 값을 만드는 것(함수 스코프 활용)이 클로져의 개념!

// 예제코드 1
const func1 = () => {
  const name = 'hwang';
  const closureFunc = () => {
    console.log(name);
  };
  return closureFunc;
};

const result = func1();
result(); // 'hwang'
console.log(name); // 스코프가 때문에 name에 접근 할 수 없음!
            ^
// ReferenceError: name is not defined

응용 1

예제코드 1에서 본것처럼 고정값을 반화하는 클로져는 거의 사용되지 않으며, 보통 첫번째 함수의 인자로 값을 전달하면 인자를 변형하는 값을 출력하는 방식으로 사용된다.

// 예제코드 2
const func2 = (name) => {
  const greeting = name +'님 안농~!'
  const printGreeting = ()=>{
    console.log(greeting)
  }
  return printGreeting
}
const result2 = func2('hwang')
result2() // 'hwang님 안농~!'

그래서, 🤔 클로져는 누구야 ?

최고 밖에 선언된 함수 ? 내부에 선언된 함수? 누가 클로져인데!?
3개의 함수가 등장하는데 결론적으로 클로져는 result2이다!

응용 2

클로저 함수를 통해 내부 값을 수정/로드 할 수 있게 작성 (get(),set()의 방식)

// 예제코드 3
const func3 = (name) => {
  const greeting = () => console.log(name + '님 반갑습니다앗!');
  const getValue = () => {
    return console.log(name);
  };
  const setValue = (newName) => {
    name = newName;
    return console.log(name);
  };
  return {
    print: greeting,
    get: getValue,
    set: setValue,
  };
};

const { print, get, set } = func3('hwang');
print(); // hwang님 반갑습니다앗!
get(); // hwang
set('미미'); // 미미

응용 3

set(value)입력검증기록처리하기

// 입력검증 & 기록처리 예제
const func4 = (name) => {
  // 기록할 배열 선언
  const historyArray = [];
  const history = () => {
    // 기록 출력용 메서드
    return historyArray;
  };
  const setName = (newName) => {
    // 매개변수 타입 검사
    if (typeof newName === 'string') {
      name = newName;
      // set메서드로 새로운 이름 작성될때마다 기록
      historyArray.push({ code: '이름변경', newName });
      return name;
    } else {
      return '문자열이 아님';
    }
  };
  const getName = () => {
    // get메서드로 새로운 이름 작성될때마다 기록
    historyArray.push({ code: '이름로드', name });
    return name;
  };
  const printGreeting = () => {
    return name + '님, 안녕!';
  };
  return {
    set: setName,
    get: getName,
    history,
    print: printGreeting,
  };
};

const result = func4('황');
console.log(result.get());
console.log(result.set('마마'));
console.log(result.set(88));
console.log(result.history());
// [
//   { code: '이름로드', name: '황' },
//   { code: '이름변경', newName: '마마' },
// ];

응용 4

  • 잠금/잠금해제 기능 추가
    • validateLocked() 작성하여 잠금상태 확인 코드 분리
  • 암호 추가/변경
    • validatePw() 작성하여 비밀번호 확인 코드분리
const func5 = (initPw) =>{
  // 잠금상태와 비밀번호 변수 정의
  let isLock = true;
  let pw = initPw;

  // 비밀번호 확인 함수 작성
  const validatePw = inputPw => {
    if (!pw === inputPw) {
      console.log('암호틀림')
      return false
    }
    return true
  }
  // 잠금상태 확인 함수 작성
  const validateLocked = () => {
    if (isLock) {
      console.log('잠금상태');
      return false;
    }
    return true
  }
  // '잠금상태'로 설정
  const lock = () => {
   isLock = true;
  }
  // '잠금해제'로 설정
  const unlock = (curPw) => {
    if (!validatePw(curPw)) return false;
    isLock = false;
  }
  // 비밀번호 변경 메서드
  const password = (curPw, newPw) => {
    // 현재 비밀번호 맞는지 체크
    if (!validatePw(curPw)) return false;
    // 비번 맞을경우 newPw로 변경
    pw = newPw;
  } 
  const 그밖에_메서드 = () => {
    // 잠금상태확인하고 메서드 실행
    if (!validateLocked()) return false;
    return 반환 값;
  }
}
profile
TIL 기록 블로그 :: 문제가 있는 글엔 댓글 부탁드려요!

0개의 댓글