728x90
IIFE (Immediately Invoked Function Expression)
- 익명의 클로저를 통해 “privacy”를 제공하는 설계 패턴
기본 사용법
!function() {
alert("Hello from IIFE!");
}();
void function() {
alert("Hello from IIFE!");
}();
- IIFE 패턴의 핵심은 함수를 사용하여 이를 표현식으로 바꾸고 즉시 실행하는 것이다.
- 첫 번째 문자 인 !은 함수 문, 정의 대신 해당 함수를 표현식으로 만드는 것이다. 그런 다음 즉시 function을 실행한다.
- 전에 보았듯, function 문은 항상 function 키워드로 시작한다. 자바스크립트는 function키워드를 유효한 문장의 첫 단어로 볼 때마다 함수 정의가 수행될 것으로 예상한다. 그래서 이런 일이 발생하지 않도록 1번 라인의 function키워드 앞에 ! 접두사를 붙인다. 기본적으로 자바스크립트는 !다음에 오는 모든 것을 표현식으로 처리하도록 한다.
!function() {
alert("Hello from IIFE!");
}();
void function() {
alert("Hello from IIFE!");
}();
- 두 Variation 모두 널리 사용된다. 나는 개인적으로 Variation 1을 선호하는 편이다. 핵심 부분에 들어가면 두 가지 Variation가 어떻게 작동하는지 약간 다르다.
- 표현식 호출 괄호가 밖에 있든 안에 있든 문제없음
// Valid IIFE
(function initGameIIFE() {
// 게임을 초기화하는 모든 MAGIC 코드!
}());
// 두가지 IIFE 예제
function nonWorkingIIFE() {
// 괄호가 필요한 이유를 알았다!
// 이러한 괄호가 없으면 표현식이 아니라 함수 정의이다.
// 구문 오류가 발생!
}();
function () {
// 구문 에러가 발생!
}();
// 기억하라! IIFE를 형성하려면 함수 표현식이 필요합니다. 함수 문장, 정의는 IIFE를 작성하는 데 사용되지 않는다
IIFEs and private variables
- IIFE 내부에서 선언 된 변수는 외부에서 볼 수 없다. ( == 기능범위를 만들 수 있다!)
(function IIFE_initGame() { // Private variables that no one has access to outside this IIFE var lives; var weapons; init(); // Private function that no one has access to outside this IIFE function init() { lives = 5; weapons = 10; } }());
- IIFE_initGame은 IIFE, lives와 weapons는 private variable
- init와 lives,weapons은 외부에서 접근 불가능하지만 init은 lives와 weapons에 접근 가능하다.
IIFEs with a return value
var result = (function() {
return "From IIFE";
}());
alert(result); // alerts "From IIFE"
- return 값이 필요없으면 !, +, void 등으로 보았던 IIFE 변형 사용해도 된다.
- 하지만 IIFE의 장점 중 하나가 변수에 할당 할 수있는 값을 리턴할 수 있다는 것이다.
- result를 alert하면 IIFE의 리턴값을 보여준다.
IIFEs with parameters
- IIFE는 값을 리턴 할 수 있을 뿐만 아니라 IIFE도 호출되는 동안 인수를 사용할 수 있다. 간단한 예를 보자.
(function IIFE(msg, times) {
for (var i = 1; i <= times; i++) {
console.log(msg);
}
}("Hello!", 5));
- 위의 예에서 1번째 줄에서 IIFE는 각각 msg, times라는 두 개의 매개 변수를 갖는다.
- 5번째 줄에서 IIFE를 실행할 때, 지금까지 보아온 빈 괄호() 대신에 IIFE에 인수를 전달한다.
- 2-3번째 줄은 IIFE 내부의 파라미터를 사용한다.
(function($, global, document) {
// use $ for jQuery, global for window
}(jQuery, window, document));
- 위의 예제에서 우리는 3번째 줄의 IIFE에 인수로 jQuery, window 및 document를 전달합니다. IIFE 내부의 코드는 $, global, document로 각각 참조 할 수 있다.
- JavaScript는 항상 현재 함수의 범위에서 범위 조회를 수행하고 식별자를 찾을 때까지 상위 범위에서 계속 검색한다. 3번째 줄로 document를 전달할 때 document의 로컬 scopes를 벗어나는 scopes 조회를 수행하는 유일한 경우이다. 문서화 할 IIFE의 모든 참조 사항은 IIFE의 지역 범위를 넘어 조회 할 필요가 없다. jQuery에도 똑같이 적용된다. 이것에 의한 성능 향상은 IIFE 코드가 얼마나 사소하고 복잡한 지에 따라 거대한 것은 아니지만 여전히 유용한 유용한 트릭이다.
- 또한 JavaScript minifier는 함수에서 선언 된 매개 변수 이름을 안전하게 축소 할 수 있다. 이러한 매개 변수를 매개 변수로 전달하지 않으면 minifier가이 함수의 범위를 벗어나는 문서 또는 jQuery에 대한 직접 참조를 축소하지 않는다.
ES6로 IIFE를 대신한다?
//IIFE
(function() {
var scoped = 42;
}());
console.log(scoped); // ReferenceError
//ES6
{
let scoped = 42;
}
console.log(scoped); // ReferenceError
- 둘은 동일하게 작동함
var myModule = (function() {
// private 변수, IIFE 안에서만 접근할 수 있다.
var counter = 0;
function increment() {
counter++;
}
// 외부로 노출되는 로직
return {
increment: increment
}
}());
// myModule.js
let counter = 0;
export function increment() {
counter++;
}
// logic.js
import {increment} from 'myModule.js';
increment();
- 이 둘도 동일하게 작동
const SENTENCE = 'Hello world, how are you?';
const REVERSE = (() => {
const array = [...SENTENCE];
array.reverse();
return arr.join('');
})();
- IIFE를 사용하는 경우는 즉시 호출되는 화살표 함수를 사용할 때이다. 때로는 단일 표현식이 아니라 일련의 구문을 통해서만 결과를 생성할 수 있으며, 이러한 구문을 인라인화 하려면 즉시 함수를 호출해야 한다;
Module
- js 코딩은 변수 관리가 중요하다. - Scope를 통해 변수 유지관리를 하는데 이 때 다른 scope에서 같은 변수를 사용할 경우 전역변수 처리를 해서 함께 사용할 수 있다. - 하지만 전역 변수로 만들어 사용할 시 발생할 수 있는 여러문제가 존재해서, 이를 해겨하기 위해 모듈을 사용한다.
모듈을 사용하는 이유
- 모듈은 이러한 변수와 함수를 구성하는 더 좋은 방법을 제공합니다. 모듈을 사용하면 함께 사용하기에 적합한 변수와 함수를 그룹화 할 수 있습니다. 이러한 함수와 변수를 모듈 범위에 넣습니다. 모듈 스코프를 사용하여 모듈의 함수간에 변수를 공유 할 수 있습니다.
- 그러나 함수 범위와 달리 모듈 범위는 변수를 다른 모듈에서도 사용할 수 있는 방법을 제공합니다. 모듈의 어떤 변수, 클래스 또는 함수가 사용 가능해야하는지 명시 적으로 말할 수 있습니다. 다른 모듈에서 사용할 수있는 것이 있으면 이를 export라고합니다. export를하면 다른 모듈은 해당 변수, 클래스 또는 함수에 의존한다고 명시 할 수 있습니다.
- 모듈은 명시적인 관계이기 때문에 다른 모듈을 제거하면 어떤 모듈이 파손될지를 알 수 있습니다.
- 일단 모듈들 사이에 변수를 export하고 import 능력을 갖게 되면, 당신의 코드를 서로 독립적으로 작동할 수 있는 작은 덩어리로 분해하는 것을 훨씬 더 쉽게 만듭니다. 그런 다음 이 덩어리를 결합하고 다시 결합하면, 마치 레고 블록과 같은, 동일한 모듈에서 모든 종류의 어플리케이션을 만들 수 있습니다.
- 모듈이 매우 유용하기 때문에, 자바스크립트에 모듈 기능을 추가하려는 시도가 여러 번 있었습니다. 오늘날에는 두 가지 모듈 시스템이 활발하게 사용되고 있습니다. CommonJS(CommonJS, CJS)는 Node.js가 역사적으로 사용해 온 것이다. ESM(EcmaScript 모듈)은 자바스크립트 규격에 추가된 최신 시스템입니다. 브라우저는 이미 ES 모듈을 지원하며, Node는 지원을 추가하고 있습니다.
- 장점 :
- 코드는 작은 파일들로 분할될 수 있습니다.
- 어느 애플리케이션에서(애플리케이션의 어디든지) 동일한 Module을 공유할 수 있습니다.
- 이상적으로, Module들은 다른 개발자들에 의해 검증될 필요가 없습니다. 왜냐하면 Module들의 기능이 입증되었기 때문입니다.(일부 의역 : works을 기능으로)
- Module을 참조하는 코드는 의존성을 이해합니다. Module 파일이 변경되거나 이동되면 즉시 문제가 됩니다.
- Module 코드는 (보통) 네이밍 중복을 줄이는데 도움을 줍니다. module1에서의 함수 x()는 module2에서 함수와 충돌이 되지 않습니다. 네임스페이스와 같은 옵션들이 사용되어서 module1.x() 와 module2.x()이 됩니다.
작동방식
- 모듈을 사용하여 개발할때 의존성 그래프를 작성합니다. 서로 다른 종속성 사이의 연결은 사용하는 모든 import 문에서옵니다.
- 이 import 문은 브라우저 또는 Node가 로드해야하는 코드를 정확히 인식하는 방법입니다. 그래프의 진입점으로 사용할 파일을 제공합니다. 여기에서 나머지 코드를 찾으려면 import문을 따르면 됩니다.
728x90
'Programming Language' 카테고리의 다른 글
JS33 - 09.이벤트루프(Eventloop) (0) | 2021.06.02 |
---|---|
객체지향 프로그래밍이란? (0) | 2021.06.01 |
JS33 - 07.표현식과 구문(expression vs statement) (0) | 2021.05.31 |
JS33 - 06.함수 범위, 블록 범위, 렉시컬(lexical) 범위 (0) | 2021.05.31 |
JS33 - 05.== and === and typeof (0) | 2021.05.31 |
댓글