[Study] Deep Dive - 스코프

M_yeon·2023년 4월 15일
0

Deep Dive

목록 보기
5/6
post-thumbnail

해당 챕터를 담당하게 됐으므로 작성한다....
그래도 개발 공부를 처음 시작할때 짚고 넘어간 부분이라 편하다 깔깔

변수의 생명 주기

이 책의 초반에도 나와 있듯이 변수를 선언하고 사용하게 되지만
더 이상 사용하지 않을때는 가비지 컬렉터가 메모리에서 이 변수를 삭제 한다고 했다.
이처럼 사용하지 않는데 메모리를 차지하고 삭제되지 않는다면 문제가 생긴다는 내용이다.

4장에서 다룬 내용에는 변수를 선언하면 런타임 이전에 초기화가 되어 undefined가 되지만 함수 안! 즉, 지역 변수로 선언하게 된다면 런타임에 함수가 실행되지 않는 한 호이스팅이 되지 않는다
지역 변수는 함수가 실행될 때 할당 되지만 함수가 종료되면 더 이상 참조할 수 없게 된다.

하지만 함수가 종료되더라도 해당 값을 계속 참조할 수 있는 케이스가 있다.
재귀함수~


변수 == 메모리 공간을 식별하기 위한 이름
변수의 생명주기는 메모리 공간이 확보된 시점부터 메모리 공간이 해제되어 가용 메모리 풀에 반환되는 시점까지다.

함수 내부에서 선언된 지역 변수는 함수가 생성한 스코프에 등록된다.
함수가 생성한 스코프는 렉시컬 환경이라 부르는 물리적인 실체가 있다고 했다.

쉽게 말해, 스코프체인이 일어나는 과정 중 지역 변수인지, 전역변수인지 메모리 공간이 먼저 설정되고 그 안에 키(변수명 즉, 식별자)가 등록되고 할당이 일어나는 시점에서 비로소 그 값을 사용할 수 있게 되는것이다.

따라서 변수는 자신이 등록된 스코프가 소멸될 때까지 유효하다.
객체라서 가비지 컬렉터가 해당 객체 메모리 값을 삭제할 때까지는 사용할 수 있다는 말같다.

이때 메모리 풀에 반환된다.
어디선가 이 스코프를 참조하고 있다면 당연히 삭제되지 않는다 이는 클로저와 아주 깊은 연관이 있는데 자세한 내용은 해당 챕터가 나올 때 자세히 다뤄 보겠다.

함수를 어디서 호출 했는지가 아니라 함수를 어디서 정의 했는지에 따라 상위 스코프를 결정하기 때문에, 함수가 호출된 위치는 상위 스코프 결정에 어떠한 영향도 주지 않는다.

var x = 'Hey';

function GetOut() {
	console.log(x); // undefined
	var x = 'Nope'
}

GetOut();
console.log(x); // Hey 출력

GetOut 안에서 x를 찍었을 때 당연히 전역변수니까 Hey가 나오겠지라고 생각할 수 있지만 함수는 런타임 때 실행되기 때문에 선언 단계라 undefined가 실행되는 것이다.
함수 내에서 다시 할당 해주기 전까지는 undefined가 출력된다.

이처럼 호이스팅은 스코프 단위로 동작한다.
전역변수와 지역변수의 호이스팅은 차이가 있다는걸 인식하자. 간단하다!

전역 변수는 전역에서 끌어 올려진것 같지만 런타임 이전에 동작을 하는 무언가 있을 뿐이고
지역변수는 런타임 때 && 함수가 실행되어야 호이스팅이 된다는 뜻이다.

호이스팅은 변수 선언이 스코프의 선두로 끌어 올려진 것처럼 동작하는 자바스크립트 고유의 특징을 말한다.

스코프 단위로 동작한다는것이 전역이냐, 지역이냐 이 말이다,,, 변수가 선언된 스코프가 뭐냐를 인식하고 그 안 제일 선두로 끌어 올려진다는 뜻이다~

전역번수로 사용하면 파일이 나뉘어져 있다고 해도 컴파일때 하나로 합쳐지므로 겹치는걸 주의해야 하지만 편하게 사용할때는 스타일이나, 데이터의 값을 모든 파일에서 공유해야 할때 편리하게 사용할 수 있다. 이는 팀원과 상의해서 같이 만들도록 해보자

export const styleSet = {
  colors: {
    white: '#ffffff',
    black: '#000000',
    gray: '#cccccc',
    darkGray: '#777777',
    lightGray: '#eeeeee',
    primary: '#e47e7e',
    subColor01: '#FA8F7D',
    subColor02: '#F09B78',
    subColor03: '#FA7DBB',
    subColor04: '#F078F0',
    subColor05: '#ffdddd',
    tp: 'transparent',
    fail: 'red',
    officeGo: '#1354d9',
    officeLateness: '#bf0920',
    officeNone: '#d27300',
    officeVacation: '#01853d',
  },
  fonts: {
    L: 'SCDream2',
    M: 'SCDream3',
    B: 'SCDream4',
    EB: 'SCDream5',
  },
  fontSizes: {
    big: '2.125rem',
    subTitle: '1.625rem',
    strong: '1.25rem',
    normal: '1rem',
    small: '0.8rem',
  },
  breakPoints: {
    mobile: '(max-width: 767px)',
    tablet: '(max-width: 1024px)',
    deskTop: '(max-width: 1300px)',
  },
};

사용하고 싶을땐 언제든지 color: {styleSet.color.red} 이런식으로 사용하면 된다.


모듈패턴

모듈 패턴은 클래스를 모방해서 관련이 있는 변수와 함수를 모아 즉시 실행 함수로 감싸 하나의 모듈을 만든다.이는 자스의 강력한 기능인 클로저를 기반으로 동작한다.

(function () {
 /* 이런식으로 사용하게 되지만 
  HOF와도 연관이 있고 후에는 권한분기할 때 많이 사용했던것 같다.
  콜백함수도와도 연관이 있고,,,
  정보은닉을 할 때도 많이 사용한다.
 */
})

ES6 모듈을 사용하면 전역변수를 사용할 수 없다.
ES6 모듈은 파일 자체의 독자적인 모듈 스코프를 제공한다.
따라서 모듈 내에서 var 키워드로 선언한 변수는 더즌 전역 변수가 아니며 window 객체의 프로퍼티도 아니다.

음,, 이책이 꽤 예전에 나온거라 차이점이 있을지 모르지만
요즘은 webpack등의 모듈 번들러를 사용하는것이 일반적이다 까지만 짚고 넘어가겠다.
이 webpack에 대해서 공부를 하다보면 굉장히 시야가 넓어지는것을 느낄 수 있었다.


회고

디버깅으로 확인해보느라 시간 가는줄 몰랐다.
클로저, 렉시컬 스코프 자세히 디버깅해보고 짚고 넘어가는 시간이었고 메모리 참조까지 알아보며 재밌었다

0개의 댓글