아하
검색 이미지
생활꿀팁 이미지
생활꿀팁생활
생활꿀팁 이미지
생활꿀팁생활
검소한불곰47
검소한불곰4721.03.03

안녕하세요.. 자바스크립트 공부 중 궁금한게 생겨 질문 드립니다.

var testModule = (function () { var counter = 0; return { incrementCounter: function () { return counter++; }, resetCounter: function () { console.log( "counter value prior to reset: " + counter ); counter = 0; } }; })();

위 코드에서 function을 ()로 감싸주는 이유가 무엇인가요?

그냥 testModule = function() {} (); 로 실행해서 결과를 받아도 동일하지 않은가요?

다른 이유가 있는건가요?

55글자 더 채워주세요.
답변의 개수3개의 답변이 있어요!
  • 탈퇴한 사용자
    탈퇴한 사용자21.03.04

    본문의 코드는 counter라는 함수 내부의 변수를 증가시키는 incrementCounter 함수와, 초기화를 시켜주는 resetCounter 함수를 가지고 있는 객체(함수)입니다.

    위와 같이 (function() {})(); 로 testModule 을 만들게 되면 해당 변수는 아래와 같이 사용을 할 수 있습니다.

    > testModule.incrementCounter(); 0 > testModule.incrementCounter(); 1 > testModule.incrementCounter(); 2

    만약 궁금해하는 것처럼 본문의 코드를 아래와 같이 function을 ()로 감싸지 않고 바로 함수로 만들어서 실행을 해보면 testModule2 는 함수라는 타입입니다.

    var testModule2 = function () { var counter = 0; return { incrementCounter: function () { return counter++; }, resetCounter: function () { console.log( "counter value prior to reset: " + counter ); counter = 0; } }; };

    하지만 아래와 같이 incrementCounter() 로 호출을 하면 반환 값은 계속 0입니다.

    > testModule2().incrementCounter() 0 > testModule2().incrementCounter() 0 > testModule2().incrementCounter() 0 > testModule2().incrementCounter() 0 > testModule2().incrementCounter() 0 > testModule2().incrementCounter()

    왜냐하면 testModule2() 이 호출할 때마다 새로운 객체가 만들어지기 때문입니다.
    만약 첫 번째 실행한 것처럼 하기 위해서는 만들어진 객체를 변수에 담아야 합니다.

    > var module2 = testModule2(); undefined > module2.incrementCounter(); 0 > module2.incrementCounter(); 1 > module2.incrementCounter(); 2

    testModule과 testModule2는 왜 이런 다른 동작을 보여줄까요?
    typeof 로 타입을 확인해보면 다른 결과를 보여줍니다.

    > typeof testModule 'object' > typeof testModule2 'function'

    testModule은 타입이 'object'이고, testModule2는 'function'입니다.

    testModule은 이미 함수로 만들어진 객체입니다. 그래서 제일 처음 예제처럼 incrementCounter() 를 호출했을 때 counter가 누적되며 증가를 하게 됩니다.

    결론을 내려보면 function을 ()로 감싸주는 것과 감싸주지 않는 것은 동작이나 사용 방법에 차이가 있다는 것을 알 수 있습니다.

    추가적으로 자바스크립트에서 클로저(Clousure) 라는 개념에 대해 더 알아보시면 도움이 될 것 같습니다.


  • 펑션을 감싸주고있는 부분을 "즉시실행함수" 라고 합니다.

    말 그대로 펑션을 별도로 호출하지 않아도 이미 자동으로 호출되어 버립니다.

    물론 직접 호출한 것과 결과적으론 똑같아요.

    기본적인 차이점은 즉시실행함수가 아닐때는 함수를 선언하고 변수에 할당하는 과정을 거치지만,

    즉시실행함수를 사용했을경우엔 저런 일련의 과정이 없이 실행되어 버립니다.

    그래서시 초기화 init 단계에서 많이 쓰이고 있죠.

    표기법으론 (function aa(){}()) 이런식으로 많이 쓰지만

    앞의 괄호를 생략해서 function aa(){}() 써도 됩니다.

    하지만 제일앞에 괄호를 붙여주는건 가독성 측면에서 더 유리하기 때문에 붙여주는것이 좋습니다. ^^

    보다 깊이있는 이해를 위해선 "즉시실행함수"로 조회 해보시면 많은 자료가 있으니 참고 하시기 좋을것 같습니다.


  • 즉시실행함수를 사용하기 위함입니다. 질문자님께서 적어주신 function(){}(); 는 함수가 실행이 되지 않습니다.

    자바스크립트는 1급객체입니다. 그 성질중 하나는 변수에 함수를 넣을수 있다는 것인데요.

    즉 testModule 이라는 변수에 (function(){})() 즉시 실행함수를 실행시켜(다른 코드에서 함수를 실행하는 것이 아닌 프로그램이 실행되자마자 함수가 실행되게끔 하는 방법) 해당 함수에 대한 내용을 변수에 담는 것입니다.

    위의 코드는 자바스크립트 디자인패턴인 모듈패턴을 참고한 내용이네요.