Muscardinus
Closures 본문
728x90
Closure는 함수로 하여금 자신의 Scope을 감싸고 있는 함수의 변수에 접근을 할 수 있게 돕는다. JS 엔진에서는 Call Stack 밖으로 나가고 나서도 Garbage Collection으로 이 변수들을 없애지 않고 남겨두기 때문에 가능한 것 이다.
function a() {
let grandpa = "grandpa";
return function b() {
let father = "father";
let random = 12345; // not referenced, will get garbage collected
return function c() {
let son = "son";
return `closure inherited all the scopes: ${grandpa} > ${father} > ${son}`;
};
};
}
a()()();
// closure inherited all the scopes: grandpa > father > son
const closure = (grandma) => (mother) => (
daughter
) => `${grandma} > ${mother} > ${daughter}
`;
// grandma > mother > daughter
그렇다면 Closure를 사용하면 무엇이 좋을까?
Memory Efficiency
function inefficient(idx) {
const bigArray = new Array(7000).fill("!");
console.log("created!");
return bigArray[idx];
}
const getEfficient = efficient();
function efficient() {
const bigArray = new Array(7000).fill("!");
console.log("created again!");
return function (idx) {
return bigArray[idx];
};
}
inefficient(688);
getEfficient(688);
위 코드를 보면 알 수 있듯이, 두 함수 모두 같은 결과물을 반환하지만, inefficient 함수는 호출 될 때 마다, 배열이 선언되지만, getEfficent 함수는 한 번 만, 배열이 선언된다. 이를 통하여 우리는 메모리 효율성을 얻을 수 있다.
Encapsulation
const encapsulation = () => {
let people = [];
const setName = (name) => people.push(name);
const getName = (idx) => people[idx];
const rmName = (idx) => people.splice(idx, 1);
return {
setName,
getName,
rmName,
};
};
const data = encapsulation();
data.setName("Brittney"); // 0
data.getName(0); // 'Brittney'
data.rmName(0); // ['Brittney']
// you have no access to the array people
// can only change it via methods provided
위 코드에서 볼 수 있듯이, data는 한 개의 Object를 반환하고 그 안에는 3개의 함수가 존재한다. 하지만, 직접적인 people 배열에 대한 접근은 불가능하다. 우리는 이를 통하여 접근을 원하지 않는 변수를 통제할 수 있다.
728x90
'FrontEnd > JavaScript Basics' 카테고리의 다른 글
Asynchronous JS (Promise) (0) | 2020.12.18 |
---|---|
Higher Order Functions (0) | 2020.12.17 |
Prototype (0) | 2020.12.17 |
Lexical Environment (0) | 2020.12.16 |
Hoisting (0) | 2020.12.16 |
Comments