Dev-dotoli TIL

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

// 아 넘모 어려움


어려운거 알아 처음 프로그래밍 시작하시는 분들 모를 수 있음

하지만 중급 개발자, 고급 개발자가 되기 위해서는 반드시 익혀야 함

힘내