[JS] 자료형, 가비지 콜렉션, 클로저

홍인열·2021년 9월 8일
0

원시자료형

자바스크립트에서 원시 타입의 데이터는 객체가 아니면서 method를 가지지 않는 6가지 타입
string,number,boolean, undefined, symbol, (null)

  • 원시자료형이 할당될 때에는 변수에 값(value) 자체가 담긴다.
  • 값(value)는 "하나"의 정보, 데이터이다.
  • 원시자료형이란 이름이 붙게된 배경으로는 데이터 저장소용량이 제한되던 시기에는 변수에 데이터 용량이 제한된 하나의 원시 자료형 밖에 담을 수 없었기 때문이고 한다.
  • null은 원시자료형처럼 사용되지만 엄밀히 따지면 객체라고 한다.

참조자료형

자바스크립트에서 원시 자료형이 아닌 모든 것은 참조 자료형이다.
Array[], Object{}, function(){} 이 대표적이다.

  • 참조자료형이 할당될 때에는 변수의 값이 아닌 특정 주소를 저장한다.
  • 동적으로 크기가 변하는 데이터를 heap이라불리는 곳에 저장하고 그 주소를 변수에 할당한다.
const arr1 = ['apple', 'banana']
let arr2 = ['apple', 'banana']
console.log(arr1)
// => ['apple', 'banana']
console.log(arr2)
// => ['apple', 'banana']
console.log(arr1 === arr2)
// => false 두개의 배열이가지고 있는값은 갖지만 그배열을 저장하고 있는 주소는 다르다!
arr2 = arr1 
// arr2에 arr1의 주소를 할당한다.
console.log(arr1)
// => ['apple', 'banana']
console.log(arr2)
// => ['apple', 'banana']
console.log(arr1 === arr2)
// => true!
arr2[1] = "mango" 
//arr2, arr1이 같은 주소를 할당받고 있어서 동일한 객체에 접근이 가능하다.
console.log(arr1)
// =>['apple', 'mango']

종합하면 변수에는 하나의 값 또는 참조형데이터의 주소가 저장된다는 것이다!!

그런데, 참조형 데이터를 사용하다가 더이상 참조를 하지않게되면 해당 하는 주소에 저장되있던 객체와같은 데이터들은 어떻게 되는거지?? 나중에 다시 불러올수 있는건가?? 라는 의문이 생겨서 찾아 보았다!!

가비지 콜렉션

자바스크립트와 같은 고수준 언어들은 "가비지 콜렉션(GC)"이라는 자동 메모리 관리 방법을 사용한다
참조-세기 알고리즘은 가장 소박한 알고리즘이다. 이 알고리즘은 "더 이상 필요없는 오브젝트"를 "어떤 다른 오브젝트도 참조하지 않는 오브젝트"라고 정의한다. 이 오브젝트를 "가비지"라 부르며, 이를 참조하는 다른 오브젝트가 하나도 없는 경우, 수집이 가능하다. -MDN-
즉, 더이상 참조되지 않는 참조형 데이터는 자동으로 제거된다는 말이다.

클로저

짧게 말하면 '외부함수의 변수에 접근 할 수 있는 내부함수!' 라고 할 수 있겠다.
MDN의 설명을 가져와보면, '클로저는 함수와 함수가 선언된 어휘적 환경의 조합이다.'..음.. 바로 와닿는 문장은 아닌거같다..
필자가 이해한바로, 클로저는 함수 내에 변수를 선언하고 return 값으로 함수를 선언했을때! 외부함수를 특정 변수에 할당하면, 이 변수는 return된 내부 함수를 할당받게 되는것과 같다. 여기서 내부함수를 할당받았지만, 외부함수에서 선언된 변수 또한 가지고있다. 단순히 내부함수만 가지고 있는상태가 아니라는 것이다.
아래를 봐보자.

const morningOrEvening = function (time) {
  let when = time;
  return function (name) {
    return `Good ${when}, ${name}!!`
  }
}
const morning = morningOrEvning('morning'); // 외부함수를 실행하며 내부 변수에 morning을 할당해 주었다.
const evening = morningOrEvning('evenning'); // 외부함수를 실행하며 내부 변수에 evening을 할당해 주었다.
console.log(morning);
// => ƒ (name) {return `Good ${time}, ${name}!!`}
console.log(evening);
// => ƒ (name) {return `Good ${time}, ${name}!!`}
// 변수 morning과 evening에는 동일하게 내부함수가 할당되어있다. 똑같이 생겼다!
// 하지만!!!
console.log(morning('hiync'));
// => 'Good morning, hiync!!'
console.log(evening('hiync'));
// => 'Good evenning, hiync!!'

return 값을 살펴보면 내부함수의 변수 when에 변수가 할당된 상태로 사용된 것을 확인 할 수 있고, when에 변수가 할당된 시기는 morning과, evening 변수를 선언할때 이다. 단순히 리턴된 함수만 변수에 저장된게 아니고 그당시의 외부함수의 변수 또한 같이 저장이 된다. 이때 저장된 변수는 수정이 불가능하능하게 되며 이를 캡슐화라고 부른다. 그리고 return되는 함수를 매개변수를 다르게하거나, 혹은 객체의 속성형태로 함수를 선택하는 등의 수를 통해 변수에 지정된함수를 여러쓰임에 사용하는 것을 모듈화라고 한다(설명이 좀 이상하지만..).
이게 클로저함수다!

profile
함께 일하고싶은 개발자

0개의 댓글