• 카테고리

    질문 & 답변
  • 세부 분야

    프론트엔드

  • 해결 여부

    미해결

IIFE관련 질문드립니다!

22.03.03 15:41 작성 조회수 186

0

var math = math || {};
(function() {
  function sum(a, b) {
    return a + b;
  }

  math.sum = sum;
})();

 

위와같이 즉시실행함수로 감싸서 스코프의 제한을 두는건 이해 했는데 math변수 자체가 전역스코프에 선언 돼 있기 때문에 결국 sum이라는 함수가 전역객체 내의 math의 메소드로 선언된거 처럼 보입니다. 

제가 궁금한 것은 즉시실행함수로 스코프를 제한하여도 결국 math가 전역공간에 선언돼 있어 어디서든 math에 접근이 가능한 상태가 됩니다. 따라서 

var math = math || {};

function sum(a, b) {
    return a + b;
}

math.sum = sum;

 

위와 같이 작성한 내용이랑 크게 어떤차이가 있는지 잘 모르겠어서 질문드립니다...! 

 

 

답변 1

답변을 작성해보세요.

1

즉시실행함수로 스코프를 만들어 외부에서 스코프 내부 접근을 막는다는 것을 설명하려고 한 것인데요. 주신 질문을 곰곰히 생각하니깐 설명이 충분하지 않은 것 같습니다.

다시보니 예시가 좀 적절치 않다는 생각이 듭니다.

무척 좋은 질문 주셔서 감사합니다.

음... 예시를 보면 math라는 변수가 전역공간에 선언돼 있고 즉시실행함수로 스코프 내부 접근을 막아 변수 및 함수가 math를 통해서만 접근가능한 형태로 돼 있는데 

즉시실행함수로 감싸지 않는다면 math라는 객체와 함께 math의 프로퍼티들로 선언 되어 있던 함수 및 변수들이 전부 전역공간에 놓여지게 될텐데 

제가 결국 궁금한것은 스코프를 제한해서 math라는 객체를 통해서만 접근하는것이 스코프 제한없이 전역공간에 모두 선언되어 math라는 객체로도 접근이 가능하고 sum함수에도 직접 접근이 가능한 형태보다 전역공간 오염의 위험성을 낮추고 리스크를 줄이기 위함인가요...?

사실 이 둘은 어쨋거나 math라는 변수에 어디서든 접근이 가능한 형태라 큰 차이를 모르겠어서 드린 질문이였습니다...! 

저도 명확한 질문을 드리고 싶은데 글로 적으려다 보니 글만 길어지고 명확하게 안되네요...ㅠㅠ 

다른 예시를 만들어 볼게요. 곱셈하는 multiply를 만들어 외부에 노출해 보죠.

var math = math || {};

(() => {
  function _sum(a, b) {
    return a + b;
  }

  function multiply(a, b) {
    return new Array(a).fill(b).reduce((result, digit) => _sum(result, digit));
  }

  math.multiply = multiply;
})();

console.log(_sum); // undefined
console.log(math._sum); // undefined
console.log(math.multiply(2, 3)); // 6

덧셈을 이용해 곱셈을 구현할수 있어서 multiply() 함수를 _sum() 함수를 이용해 정의 했습니다. multiply()는 외부에서 사용하도록 math 객체에 연결한 반면 _sum()은 감추기 위해 즉시실행함수 안에 정의만 해두었습니다. 필요한 함수는 노출하고 불필요한 세부 구현은 감추기 위한 의도 입니다.

자, 외부에서 사용해보면요. _sum은 윈도우 객체에도 math 객체에도 없어서 접근할수가 없습니다.(undefined 확인) 반면 multiply는 math 객체를 통해 접근할 수 있죠. 이렇게 즉시실행 함수를 사용해 세부구현은 감추고 필요한 모듈만 외부 노출켜 모듈화 할 수 있습니다. OOP의 캡슐화 이기도 하고요.

아...! 이렇게 보니 이해가 되네요 정말 감사합니다...!! 

이해되셨다니 저도 무척 기쁩니다. 그럼 나머지 수업도 열심히 들어주세요😁