자바스크립트 즉시실행함수 - jabaseukeulibteu jeugsisilhaenghamsu

**즉시 실행 함수 표현(IIFE, Immediately Invoked Function Expression)**은 정의되자마자 즉시 실행되는 Javascript Function 를 말한다.

(function () { statements })();

이는 Self-Executing Anonymous Function 으로 알려진 디자인 패턴이고 크게 두 부분으로 구성된다. 첫 번째는 괄호((), Grouping Operator)로 둘러싸인 익명함수(Anonymous Function)이다. 이는 전역 스코프에 불필요한 변수를 추가해서 오염시키는 것을 방지할 수 있을 뿐 아니라 IIFE 내부안으로 다른 변수들이 접근하는 것을 막을 수 있는 방법이다.

두 번째 부분은 즉시 실행 함수를 생성하는 괄호()이다. 이를 통해 자바스크립트 엔진은 함수를 즉시 해석해서 실행한다.

예제

아래 함수는 즉시 실행되는 함수 표현이다. 표현 내부의 변수는 외부로부터의 접근이 불가능하다.

(function () { var aName = "Barry"; })(); // IIFE 내부에서 정의된 변수는 외부 범위에서 접근이 불가능하다. aName // throws "Uncaught ReferenceError: aName is not defined"

IIFE를 변수에 할당하면 IIFE 자체는 저장되지 않고, 함수가 실행된 결과만 저장된다.

var result = (function () { var name = "Barry"; return name; })(); // 즉시 결과를 생성한다. result; // "Barry"

같이 보기

  • Quick example (at the end of the "Functions" section, right before "Custom objects")
  • IIFE (Wikipedia)
  • Glossary
    • Function
    • Self-Executing Anonymous Function

안녕하세요 여러분! 에이블디 입니다!

이번 시간에는 즉시 실행 함수에 대해 알아볼게요!

즉시 실행 함수는 함수를 정의함과 동시에 실행하는 함수인데요, 이전 시간에 함수를 사용하는 것을 보면 함수를 선언하고 선언한 함수를 호출하는 방식으로 함수를 사용했던 것 기억나시나요?

즉시 실행 함수는 함수를 선언하자마자 바로 호출하는 특징을 가지고 있어 기존의 함수를 실행하는 과정들을 거치지 않는 특징이 있습니다.

즉시 실행 함수의 사용법은 코드를 보며 알아보도록 할게요!

( function() { console.log("즉시 실행 함수 사용법 1."); } )();( function() { console.log("즉시 실행 함수 사용법 2."); } ());

즉시 실행 함수의 사용법은 큰 틀로 보면 위의 두 가지 방식으로 나누어 볼 수 있습니다.

즉시 실행 함수는 함수 선언 소스 전치를 괄호로 묶는다고 생각하면 이해하기 쉬운데요, 첫 번째 방법은 소스를 묶는 괄호 뒤에 인수가 들어갈 괄호를 작성한 방법이고 두 번째 방법은 소스를 묶는 괄호 앞에 인수가 들어갈 괄호를 작성한 방법입니다.

즉시 실행 함수는 하나의 식이기 때문에 소스 끝에 세미콜론(;)을 붙여주셔야 합니다.

위의 작성법은 익명 즉시 실행 함수로 사용했는데요, 기존의 함수 사용법처럼 이름을 넣어서 사용할 수도 있습니다.

( function result() { console.log("함수 이름을 작성한 즉시 실행 함수."); } ());

이렇게 result라는 함수 이름을 작성해 사용할 수 있는 거죠.

즉시 실행 함수도 변수에 할당할 수 있습니다.

예제를 보면서 이해해 보도록 할게요!

지난 시간에 익명 함수를 배우면서 예제로 작성한 두 수를 더하는 함수를 즉시 실행 함수로 작성해 보겠습니다!

var result = ( function() { return 1 + 2; } ()); console.log(result);

result라는 변수에 바로 즉시 실행 함수를 선언하고 실행하여 결괏값을 할당하는 코드를 작성해 보았는데요.

3을 출력하는지 확인해 보도록 하겠습니다!

함수를 선언하고 선언한 함수를 호출하는 과정 없이 바로 함수가 실행되어 1 + 2 = 3이라는 결괏값을 출력하는 걸 확인할 수 있습니다.

조금 더 응용해서 매개 변수와 인수 값을 넣어 사용해 볼까요?

var result = ( function(a, b) { return a + b; } (3, 4)); console.log(result);

function 다음의 소괄호에 매개변수 a와 b를 넣고 함수 끝에 함수를 묶는 괄호 바로 앞 소괄호에 인수 3과 4를 넣어주신 것 보이시나요?

3과 4가 더해져서 7을 출력하는지 확인해 보도록 하겠습니다!

매개 변수 a에 3, b에 4가 넘겨져 3 + 4 = 7이라는 결괏값을 출력하는 걸 확인할 수 있습니다.

즉시 실행 함수는 초기화 코드에 많이 사용되는데요, 초기화 코드에 사용하는 가장 큰 이유는 변수를 전역으로 선언하는 것을 피하기 위해서입니다.

이번 시간에는 즉시 실행 함수에 대해 알아보았습니다.

다음 시간에 자바스크립트에 대해 더 알아보는 시간을 갖도록 할게요!

즉시실행함수에 이해하기 위해서 함께 알면 좋을것들

  • 자바스크립트 함수 : first-class object
  • 자바스크립트 Scope (function-level scope)
  • 함수 정의 ( 함수 선언식, 함수 표현식 )

자바스크립트에서 가장 큰 문제점 중의 하나는 글로벌 스코프에 정의된 것은 코드 내의 어디서든지 접근이 가능하다는 것입니다. 하지만, 외부에 공유되면 안되거나 공유될 필요가 없는 속성이나 메소드가 있습니다. 또한, 다른 스크립트 파일 내에서 동일한 이름으로 명명된 변수나 함수가 있을 경우 원치 않는 결과를 가져올 수 있습니다.

익명 함수표현식으로 함수를 하나 정의하고 실행해 보겠습니다. 그리고 외부에서 함수 내의 변수에 접근해 보겠습니다.

// 함수표현식에 의한 명시적인 함수호출 var app = function() { console.log('함수 호출'); // "함수 호출" 출력 }; app();

이번에는 익명 즉시실행함수로 함수를 정의해 보겠습니다.

// 즉시실행함수 (function() { console.log('함수 호출'); // "함수 호출" 출력 }());

위 두개의 코드는 동일한 동작을 수행합니다.

함수표현식은 함수를 정의하고, 변수에 함수를 저장하고 실행하는 일련의 과정을 거칩니다. 하지만, 즉시실행함수를 사용하면 이와 같은 과정을 거치지 않고 즉시 실행된다는 특징이 있습니다. 차이점이라면 단순히 함수를 괄호"()"로 랩핑한 게 전부입니다. 이런 함수를 즉시실행함수(IIFE)라 부릅니다.

이번에는 변수를 선언하고 이 변수에 즉시실행함수를 할당해 보겠습니다.

var app = (function() { var privateVar = 'private'; return { prop : privateVar }; }()); console.log(app.prop); // "private" 출력

콘솔에는 "private" 라고 출력됩니다.

즉시실행함수 내에서 선언한 변수를 외부에서도 접근할 수 있음을 확인할 수 있습니다. 변수의 접근 범위가 함수 내부가 아닌 외부에서도 가능해진 것입니다. 이와 같이, 즉시실행함수는 변수의 스코프를 포함하는데 사용되며 외부에서 함수 내의 변수에 접근할 경우 이를 통제할 수 있습니다. 즉시실행함수는 글로벌 네임스페이스에 변수를 추가하지 않아도 되기 때문에 코드 충돌이 없이 구현할 수 있어 플러그인이나 라이브러리 등을 만들 때 많이 사용됩니다.

아래 두개의 코드는 기명 함수표현식과 즉시실행함수에서 파라미터를 전달하는 방법을 보여줍니다.

var buyCar = function(carName) { // "내가 구매한 차는 sonata입니다." 출력 console.log('내가 구매한 차는 ' + carName + '입니다.'); }; buyCar('sonata'); (function(carName) { // "내가 구매한 차는 sonata입니다." 출력 console.log('내가 구매한 차는 ' + carName + '입니다.'); }('sonata'));

위 두개의 코드 블럭은 동일한 동작을 수행합니다. 또한, 앞서의 예제처럼 괄호"()"로 랩핑한 차이 밖에 없습니다.

과제

// 1. 함수 선언식 var hanq = a(); // alert 1 function a() { alert("1"); };

위 코드를 보면 함수선언식으로 함수가 정의되기 이전에 함수 호출이 가능하다. 함수 선언의 위치와는 상관없이 코드 내 어느 곳에서든지 호출이 가능한데 이것을 함수 호이스팅(Function Hoisting)이라 한다.

호이스팅이란 var 선언문이나 function 선언문 등을 해당 Scope의 맨 위로 옮기는 것을 말한다. 즉 자바스크립트는 코드를 실행하기 전에 var 선언문과 function 선언문을 해당 스코프의 맨위로 옮긴다.

함수선언식으로 정의된 함수는 자바스크립트 엔진이 스크립트가 로딩되는 시점에 바로 초기화하고 이를 VO(variable object)에 저장한다. 즉, 함수 선언, 초기화, 할당이 한번에 이루어진다. 그렇기 때문에 함수 선언의 위치와는 상관없이 소스 내 어느 곳에서든지 호출이 가능하다.

다음은 함수표현식으로 함수를 정의한 경우이다.

// 2. 기명 즉시실행함수 var hanq = a(); // TypeError: a is not a function (function a() { alert("1"); })(); // Douglas Crockford의 권장 표기법 (function a() { alert("1"); }());

함수선언식의 경우와는 달리 TypeError가 발생하였다. 함수표현식의 경우 함수 호이스팅이 아니라 변수 호이스팅이 발생한다.

변수 호이스팅은 변수 생성 및 초기화와 할당이 분리되어 진행된다. 호이스팅된 변수는 undefined로 초기화 되고 실제값의 할당은 할당문에서 이루어진다.

함수표현식은 함수선언식과는 달리 스크립트 로딩 시점에 변수 객체(VO)에 함수를 할당하지 않고 runtime에 해석되고 실행되므로 이 두가지를 구분하는 것은 중요하다.

JavaScript : The Good Parts의 저자이며 자바스크립트의 권위자인 더글러스 크락포드(Douglas Crockford)는 이와 같은 문제 때문에 함수표현식만을 사용할 것을 권고하고 있다. 함수 호이스팅이 함수 호출 전 반드시 함수를 선언하여야 한다는 규칙을 무시하므로 코드의 구조를 엉성하게 만들 수 있다고 지적한다.

또한 함수선언식으로 함수를 정의하면 사용하기에 쉽지만 대규모 애플리케이션을 개발하는 경우 인터프리터가 너무 많은 코드를 변수 객체(VO)에 저장하므로 애플리케이션의 응답속도는 현저히 떨어질 수 있으므로 주의해야 할 필요가 있다.

정리

  • 즉시실행 구문을 사용하면 javascript 가 유효범위를 선언 할 수 없다고 해도 강제적으로 private 변수를 만들어 내는 것이 가능 하다.
// i 라는 변수는 실행 시점에서만 사용되면 외부에서 접근 할수 없다. (function() { var i = 'hello world' ; }()); console.log(i) > error

즉 익명함수는 동적으로 할당되는 유효범위를 가지기 때문에 javascript 내에서 강제적인 유효범위 설정을 하는 경우 사용되게 됩니다.

함수 선언식과 함수 표현식에 따른 차이 (함수 표현식 방법을 권장) 


이유 ? 

함수 표현식은 함수 선언식과 달리 스크립트 로딩 시점에 변수 객체(VO)에 함수를 할당하지 않고 runtime에 실행됨 -> 너무 많은 코드를 변수 객체(VO)에 저장하면 어플리케이션의 응답속도가 떨어짐

Javascript 모듈 패턴


javascript 의 모듈 패턴은 javascript 의 코드 관리 기법 중하나로서 javascript의 특성상 객체 핸들링을 위한 방법론중 하나이다.

javascript 의 모듈 패턴은 일반적인 유효범위를 설정하는 언어에서와 같이 private 와 public 등의 캡슐화를 사용하는 방법이다.

javascript 에서 함수 혹은 변수객체를 다룰때 중복된 name 사용으로 인한 문제를 방지하기 위해 주로 namespace 방법이 사용된다. 이는 global 영역에 객체 고유의 영역을 지정하고 변수와 함수 할당을 해당 namespace 하위로 두게 하여 중복된 name 으로 인한 오류를 피하는 방법이다.

모듈 패턴은 이 네임스페이스 페턴에 언어적 유효범위를 추가 해논 것이라 이해하면 쉽다.

모듈을 작성함에 있어서 return 구문을 이용하여 공개될 영역과 내부적으로 처리할 영역을 구분하여 공개여부를 선택하게 하는 것이다.

// namespace 패턴 var myApp = myApp || {}; // 네임 스페이스 선언 myApp.hanq= function() { return 'hanq'; }; myApp.helloworld = function() { return 'hello world'; } // 모듈 페턴 var Messages = {h : 'hello', w : 'world', insane:'insanehanq'}; var myApp = (function(msg) { var helloworld = msg.h+' '+msg.w; var helloinsanehanq = msg.h+' '+msg.insane; var printInsane = function () { return helloinsanehanq; }; var printhello = function() { return helloworld; }; return { foo1 : printInsane, foo2 : printhello }; })(Messages); console.log(myApp.foo1()); > hello insanehanq console.log(myApp.helloworld); > undefined

참고한 사이트

  • Function Declarations(함수선언) vs Function Expressions(함수표현)
  • Javascript : 함수(function) 다시 보기

Toplist

최신 우편물

태그