Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | ||||||
2 | 3 | 4 | 5 | 6 | 7 | 8 |
9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 | 17 | 18 | 19 | 20 | 21 | 22 |
23 | 24 | 25 | 26 | 27 | 28 |
Tags
- 뉴 컨피던스
- 공헌감
- 레퍼런스 복사
- kubernetes
- 쿠버네티스
- Infresh
- HTML
- sentry
- 도파민형 인간
- colllection
- 이펙티브 자바
- 참조 계수
- 월칙
- 과제의 분리
- 수부타이
- java
- apache kafka
- Container
- node
- 비메모리 자원
- 아웃풋법칙
- ESG
- CSS
- docker
- 부자의그릇
- 모두가 기다리는 사람
- try-with-resources
- 히든 스토리
- 칭기즈칸의 위대한 장군 수부타이
- try width resources
Archives
- Today
- Total
Hi
클로저 본문
클로저
클로저의 개념
외부 함수의 컨텍스트가 반환되더라도 변수객체는 반환되는 내부 함수의 스코프 체인에 그대로 남아있어야만 접근할 수 있다. 이것이 바로
-> 클로저 : 이미 생명 주기가 끝난 외부 함수의 변수를 참조하는 함수
ex) outerFunc에서 선언된 x와 같은 변수를 자유 변수(Free variable)라고 한다. closure라는 이름은 함수가 자유 변수에 대해 닫혀있다(closed, bound)는 의미. -> 자유 변수에 엮여있는 함수 (우리말로 표현하자면)
- 자바스크립트로 클로저를 구현하는 전형적인 패턴 -
function outerFunc() {
var x = 1;
return function() { <- 클로저
/* x와 arguments를 활용한 로직 */
} //
}
var new_func = outerFunc();
/* outerFunc 실행 컨텍스트가 끝났다 */
new_func();
[NOTE] 클로저는 여러 언어에서 차용되고 있는 특성이다. 특히 함수를 일급 객체로 취급하는 언어(함수형 언어 functional language)에서 주요하게 사용되는 특성이다.
클로저의 활용
특정 함수에 사용자가 정의한 객체의 메서드 연결하기
function HelloFunc(func) {
this.greeting = "hello";
}
HelloFunc.prototype.call = function(func) {
func ? func(this.greeting) : this.func(this.greeting);
} // this.func와 this.greeting의 this는 생성된 인스턴스를 가리킨다.
var userFunc = function(greeting) {
console.log(greeting);
}
var objHello = new HelloFunc();
objHello.func = userFunc;
objHello.call(); // (출력결과) Hello
function saySomething(obj, methodName, name) {
return (function(greeting) {
return obj[methodName](greeting, name);
});
}
function newObj(obj, name) {
obj.func = saySomething(this, "who", name);
return obj;
}
newObj.prototype.who = function(greeting, name) {
console.log(greeting + " " + (name || "everyone") );
}
var obj1 = new newObj(objHello, "zzoon");
obj1.call();
이벤트 핸들러 형식은 function(event) {}인데, event 외의 원하는 인자를 더 추가한 이벤트 핸들러를 사용하고 싶을때, 앞과 같은 방식으로 클로저를 적절히 활용해줄 수 있다.
함수의 캡슐화
var buffAr = [
'I am ',
'',
'. I live in',
'',
'. I\'am ',
'',
' yars old.'
];
function getCompletedStr(name, city, age) {
buffAr[1] = name;
buffAr[3] = city;
buffAr[5] = age;
return buffAr.join('');
}
var str = getCompletedStr('zzoon', 'seoul', 16);
console.log(str);
buffAr이 전역변수로서 외부에 노출되어 있기 때문에, 클로저를 이용해(buffAr을 추가적인 스코프에 넣는) 이 문제를 해결할 수 있다.
var getCompletedStr = (function() {
var buffAr = [
'I am ',
'',
'. I live in',
'',
'. I\'am ',
'',
' yars old.'
];
return (function(name, city, age) {
buffAr[1] = name;
buffAr[3] = city;
buffAr[5] = age;
return buffAr.join('');
});
})();
var str = getCompletedStr('zzoon', 'seoul', 16);
console.log(str);
setTimeout()에 지정되는 함수의 사용자 정의
function callLater(obj, a, b) {
return (function() {
obj["sum"] = a + b;
console.log(obj["sum"]);
});
}
var sumObj = {
sum : 0
};
var func = callLater(sumObj, 1, 2);
setTimeout(func, 500);
setTimeout함수에 넣는 첫번째 매개변수에 인자를 넣을 수 없기 때문에, 클로저를 활용한다.
클로저를 활용할 때 주의사항
클로저의 프로퍼티값이 쓰기 가능하므로 그 값이 여러 번 호출로 항상 변할 수 있음에 유의해야 한다.
function outerFunc(argNum) {
var num = argNum;
return function(x) {
num += x;
console.log('num: ' + num);
}
}
var exam = outerFunc(40);
exam(5); // 45
exam(-10); // 35
하나의 클로저가 여러 함수 객체의 스코프 체인에 들어가 있는 경우도 있다
function func() {
var x = 1;
return {
func1 : function() { console.log(++x); },
func2 : function() { console.log (-x); }
};
};
var exam = func();
exam.func1(); // 2
exam.func2(); // -2
루프 안에서 클로저를 활용할 때는 주의하자
function countSeconds(howMany) {
for (var i = 1; i <= howMany; i++) {
setTimeout(function() {
console.log(i);
}, i * 1000);
}
}
countSeconds(3); // 4 4 4
setTimeout 함수가 실행되는 시점은 countSeconds() 함수의 실행이 종료된 이후이고, i 값은 이미 4가 된 상태이다.
해결법은 루프 i값 복사본을 넘겨 즉시 실행함수를 사용
function countSeconds(howMany) {
for (var i = 1; i <= howMany; i++){
(function(currentI) {
setTimeout(function() {
console.log(currentI);
}, currentI * 1000);
})(i);
}
}
countSeconds(3);
'WEB(웹) > javascript' 카테고리의 다른 글
클래스, 생성자, 메서드 (0) | 2018.07.07 |
---|---|
클래스 기반 언어와 프로토타입 기반 언어 (0) | 2018.07.07 |
join(), split(), includes() (0) | 2018.07.04 |
replaceAll() 구현 (0) | 2018.07.04 |
스코프 체인 (0) | 2018.07.03 |