JS 21 closure
Closure
demo24.html
내부함수(inner)가 외부함수(outter)의
맥락(context)에 접근 할 수 있는 것
- closure는 JS를 이용한 고난이도 테크닉을 구사하는데 필수적 개념
inner / outter 개념, closure적용
function outter() {
function inner() {
var title = "coding everyday";
alert(title);
}
//inner function
//var inner = function(){ }
inner();
//inner function 호출
}
outter();
// func안에서만 작동해도 되는 func이 있어서
// inner func으로 만들어서 응집성을 높인상태
function outter() {
var title = "coding everyday";
//outter function의 local variable
function inner() {
alert(title);
//변수 title이 inner에 존재하지 않을 때
//outter의 local variable에 접근
}
inner();
}
outter();
outter func가 사용되지 않을 때에도
inner func가 outter func에 접근 할 수 있음
function outter() {
var title = "coding everyday";
return function () {
alert(title);
};
}
var inner = outter();
//outter를 실행한 결과는 inner에 담음
inner();
//outter는 inner를 return했다(함수의 수명은 끝남)
//inner를 호출하는 시점에 outter의 수명이 끝났음에도
//outter의 local var에대한 접근에 성공함
closure ?
- inner func가 outter func에 접근가능
outter func는 outter func의 local var를 사용하는
inner func가 소멸될 때 까지 소멸되지 않음
private variable (비밀변수)
- software가 커지는 과정에서
어떠한 정보가 있을때 아무나 정보를 수정할 수 없게 하는 것
function factory_movie(title) {
return {
get_title: function () {
return title;
},
set_title: function (_title) {
title = _title;
},
};
}
ghost = factory_movie("Ghost in the shell");
matrix = factory_movie("Matrix");
alert(ghost.get_title());
alert(matrix.get_title());
ghost.set_title("공각기동대");
alert(ghost.get_title());
alert(matrix.get_title());
function factory_movie(title) {
return {
// 2개의 속성(method)이 있는 객체를 return
get_title: function () {
return title;
},
// outter의 title을 return
set_title: function (_title) {
title = _title;
},
};
}
//closure의 맥락에서
//method들은 inner func으로 이해할 수 있음
// factory_movie라는 함수를 호출하면서
// 인자로 Ghost in the shell, Matrix를 전달
ghost = factory_movie("Ghost in the shell");
// get_title, set_title method를 담고있는 객체를 ghost에 담음
matrix = factory_movie("Matrix");
// get_title, set_title method를 담고있는 객체를 matrix에 담음
alert(ghost.get_title());
// : Ghost in the shell
alert(matrix.get_title());
// : Matrix
// Ghost와 Matrix는 똑같은 객체를 담고있지만
// 그 객체가 가지고 있는 method가 접근하는
// outter local var는 서로 다른 상태
ghost.set_title("공각기동대");
// set_title method를 사용하면
// factory_movie의 local var를 바꿔버림
alert(ghost.get_title());
// : 공각기동대
alert(matrix.get_title());
// : Matrix
// set_title method로 ghost의 title값만 바꾸고
// matrix가 접근하는 title값에는 영향을 주지 않음
// =
// outter func가 실행될 때마다 새로운 local var를 포함하는
// closure가 생성되기 때문에 ghost와 matrix는 독립된 객체가 됨
factory_movie의 local var인 title은 return하면서 수명이 종료
그래서 inner인 get_title, set_title method를 통해서만 접근가능
title이라는 변수를 아무나 수정할 수 없게 됨
set_title method를 통해서만 수정할 수 있고
get_title을 통해서만 가져올 수 있도록 함
= title은 매우 안전하게 저장/수정되는 변수
private var 왜 필요?
- software가 커지다보면 협업, 미래의나 등이 유지보수하면서
많은 데이터를 포함하게됨 이때 아무나 수정할 수 있는 데이터가
존재하면 software가 망가질 가능성이 큼
plus
set_title: function (_title) {
if(typeof _title === 'string'){
title = _title;
} else {
alert('title은 문자열이어야 함')
}
},
//set_title method에 입력되는 값이
//문자열일때만 작동하도록 수정
closure는
JS가 private한 variable을 사용할 수 있도록 하는
아주 중요하고 좋은 mechanism임
closure 응용
demo24.html
var arr = [];
for (var i = 0; i < 5; i++) {
arr[i] = function () {
return i;
};
}
for (var index in arr) {
//for in문으로 arr에 담겨있는 값을 꺼낸다음
console.log(arr[index]());
//함수 호출
}
// 0 1 2 3 4 출력을 기대함
// : 55555
// i값이 외부변수가 아님 ?
outter func 정의하고 inner func이 outter의 local var를 참조하도록 수정
var arr = [];
for (var i = 0; i < 5; i++) {
arr[i] = (function (id) {
return function () {
return id;
};
})(i);
// )왜 추가됨? 있든없든 작동됨
// id라는 매개변수의 값으로 i값을 받아서 함수 내부로 전달
// 내부함수를 return하는데 외부함수의 지역변수 id를 씀
}
for (var index in arr) {
console.log(arr[index]());
}
// : 0 1 2 3 4
// 아 넘모 어려움
어려운거 알아 처음 프로그래밍 시작하시는 분들 모를 수 있음
하지만 중급 개발자, 고급 개발자가 되기 위해서는 반드시 익혀야 함
힘내