함수 선언식과 표현식 (맛보기)
즉시 실행 함수 표현에 대해 알아보려면 먼저 함수 선언식과 표현식에 대해 알아야한다.
아래와 같이 쓰는 것을 함수 선언식이라고 한다. 함수 선언식은 호이스팅에 영향을 받는다.
function 함수이름() {
...statements
}
아래와 같이 표현한 것을 함수 표현식이라고 한다. 함수 표현식은 호이스팅에 영향을 받지 않는다.
var 함수이름 = function() {
...statements
}
IIFE(Immediately Invoked Function Expression) : 즉시 실행 함수 표현
iffy는 말 그대로 정의되자마자 즉시 실행되는 함수를 말한다. 이러한 즉시 실행 함수는 global Scope 를 오염시키지 않기 위해 사용한다.
다양한 라이브러리들도 IIFE 패턴을 사용해 충돌을 방지하고 있다.
아래와 같이 작성할 수 있다. (1,2번이 자주 사용되고, 나머지는 그냥 알고만 있으면 된다.)
연산자를 사용한 방식은 return값이 있을 때 예상치 못한 결과가 나타날 수 있기 때문에 1,2방식이 더 널리 활용된다.
// 1.
(function() {
...statements
})();
// 2.
(function () {
...statements
}());
// 3.
!function() {
...statements
})();
// 4.
+function() {
...statements
})();
// 5.
void function() {
...statements
})();
...
Javascript는 function 이라는 키워드를 볼 때마다, 함수의 정의가 일어날 것이라고 예측한다. 그래서 그런 정의가 일어나지 않는다는 것을 알려주려고 function 키워드 앞에 !를 붙여준다. 이렇게 하면 자바스크립트는 !뒤에 무엇이 오든 표현식으로 다루게 된다. ! 뿐만아니고 +, -, ~ 등 1진 연산자에 한해서 다양한 연산자를 붙여도 같은 결과를 보인다. 단순히 뒤에 나오는 함수를 식으로 만드는 것이니까!
그니까 앞에 1진 연산자를 붙임으로서 작성한 함수가 정의되는게 아니고 식으로 표현되게 만들어 그 함수를 즉시 실행하는 것이다. 마지막의 void는 함수를 식으로 다루어지게 강제한다. 반환 값이 필요없고 단순 실행만 하기를 원한다면 이렇게 사용하면 된다.
같은 선 상에서 이런 즉시 실행 함수 표현식은 "식"의 한 종류이기 때문에, 앞서 말했던 호이스팅이 발생하지 않는다. 아래와 같이 예시를 들 수 있다.
// 함수 선언식
boo(); // 실행된다.
function boo() {
alert('booo!')
}
// 함수 표현식
bhoo(); // 실행되지 않는다.
var bhoo = function () {
alert('bhooo!')
}
// 즉시 호출 함수
(function hoo() {})();
alert(hoo()) // hoo not defined
즉시 실행 함수 표현의 장점
- 전역 스코프에 불필요한 변수를 추가해서 오염시키는 것을 방지할 수 있다.
- IIFE 내부 안으로 다른 변수들이 접근하는 것을 막을 수 있다.
- 값을 리턴해 변수에 할당할 수 있다.
- 호출될 때, 인자를 받을 수 있다.
아래의 예시를 통해 init()함수는 그 함수 바깥의 변수에 접근이 가능하지만, 바깥에서는 init 안으로 접근하지 못한다는 것을 알 수 있다.
(function example() {
// 즉시실행함수 밖에서는 사용할 수 없는 변수들
const a;
const b;
init();
// 즉시실행함수 밖에서는 사용할 수 없는 함수
function init() {
a=1;
b=2;
}
}());
아래의 예시에서는 즉시실행함수를 통해 반환된 'result입니다.'라는 string이 result 변수에 할당되는 것을 알 수 있다.
const result = (function() {
return 'result입니다.';
}());
alert(result) // 'result입니다.' 출력
IIFE는 호출시 인자를 전달할 수도 있는데, 아래와 같이 사용한다.
(function(count) {
for(let i=0; i<count; i++)
console.log("I am IIFE");
})(3);
예시
// 예제 1.
const message = (function() {
const secret = "I m scret!";
return `The secret is ${secret.length} characters long.`
})();
console.log(message); //The secret is 10 characters long.
// 예제 2.
// 호출된 함수를 가지고 있는 변수 f
const f = (function() {
let count = 0;
return function() {
return `i have been called ${++count} time(s).`
}
})();
f(); // "i have been called 1 time(s)."
f(); // "i have been called 2 time(s)."
1의 예시에서 secret은 외부에서 접근할 수 없기 때문에 안전하게 보호된다.
2의 예시에서는 함수를 호출할 때마다 새로 연산되어 값이 리턴되는 것을 알 수 있다.
참고 문헌
클로져와 같이 쓰기 좋다고 하는데.. 클로져에 관해서는 조금 더 공부해보고 같이 정리해야겠다.
뭔가 혼자 이해하기로는.. 약간 작은 Class같은 느낌이었다. 안에 return하는게 함수라 method들을 잘 사용할 수 있는 느낌..
'Woowa Techcourse > Missions' 카테고리의 다른 글
Javascript 네임스페이스 패턴(Namespace Pattern) (0) | 2021.03.10 |
---|---|
Javascript 모듈(Module) (0) | 2021.03.10 |
Javascript 호출 스택(Call Stack) (0) | 2021.03.04 |
[코드리뷰] 자동차 경주 게임 (2) | 2021.02.15 |
Number(str) vs parseInt(str) (0) | 2021.02.13 |
댓글