Modern JavaScript DeepDIve - 3

jkky98·2024년 2월 5일
0

JavaScript

목록 보기
3/6

스코프

이전에 우리는 자바스크립트 엔진의 호이스팅과정을 이해했다. 런타임과 구별되는 런타임 이전에 구축되는 것들에 대한 과정이다. 스코프개념을 이해하면 호이스팅과 런타임 과정에서 일어나는 일들을 깔끔하게 암산할 수 있다.

책에서는 지역변수와 전역변수에 대해 설명한다. 함수선언문, 변수등이 호이스팅될 때 함수 안에 있는 변수들은 어떻게 생성되는지 다음 예제를 이해하면 변수의 생명주기에 대해 알 수 있다.

var x = 'global'

function foo() {
  console.log(x)
  var x = 'local'; // (1)
}

foo();
console.log(x); // (2)

자바스크립트 엔진에 따라 호이스팅 과정에서 foo()와 x가 런타임이전에 정의될 것이다. 전역변수 x는 undefined로, function foo()는 함수 호이스팅에 따라 console.log(x)가 먼저 실행되어 undefined를 가질 것이다. 그 다음 함수내 지역변수 x가 'local'로 할당되었다가 사라진다.(호이스팅 후 전역x는 undefined, 지역x는 undefined)

런타임과정은 순서성을 가진다. 그러므로 var x = 'global'이 먼저 실행된다. 전역변수 x가 undefined에서 global로 바뀌었다. 그 후 foo()가 실행된다. foo내부 처음 코드인 console.log(x)는 지역변수x(undefined)를 반환한다. 그리고나서 x는 'local'로 선언되었다가 함수가 끝나면 다시 사라진다.
foo()함수 다음 console.log(x)에 의해 전역변수 x(global)이 반환된다.

전역 변수 주의점
전역변수를 선언하는 의도는 코드 어디서든 참조하고 할당할 수 있는 변수를 사용하겠다는 것이다. 전역 변수는 생명주기가 길며 메모리 리소스도 오랜기간 소비한다. 함수의 작성팁에서처럼 전역변수는 유지보수가 어렵다는 특징을 가진다. 최대한 지역변수를 활용하도록 하자.


전역 변수 사용 억제법

  • 즉시 실행 함수 : 함수의 생명주기를 이용
  • 네임스페이스 객체 : 그다지 유용하진 않음. 어차피 네임스페이스 객체자체가 전역변수이기 때문
  • 모듈 패턴 : 이게 짱이다. 클로저 개념과 함께 이해해야하니 뒤에서.

let, const

ES5까지 유일한 변수선언 방법은 var키워드였다. var 키워드의 단점인 중복선언을 보완하기 위해 ES6부터는 let과 const가 도입된다. let은 중복선언시 SyntaxError를 발생신킨다. var 키워드로 선언한 변수는 오로지 함수내의 코드 블록만을 지역 스코프로 인정하는 함수 레벨 스코프따르나, let은 모든 코드 블록을 지역 스코프로 인정하는 블록 레벨 스코프를 따른다.

var과 달리 let은 호이스팅이 발생하지 않는 것 처럼 동작한다(실제론 존재하긴 한다.)

console.log(foo); // ReferenceError~

let foo;
console.log(foo) // undefined

foo = 1
console.log(foo) // 1

var은 호이스팅 단계에서 선언->초기화 까지 이루어진다. 그러나 let은 호이스팅 단계에서 변수 선언만 한다. 그렇기에 런타임 환경에서 처음의console.log(foo)에서 에러를 띄운다. 하지만 이상한 점은 두번째는 왜 undefined인지이다. let foo;의 영향이 있는 것으로 보이는데 런타임에서 변수선언문을 지나고 변수에 값이 할당되기 이전까지 일시적 사각지대(TDZ)가 존재한다. 이 단계에서 초기화단계가 진행된다.

const의 경우에는 후에 더 자세히 볼 것이지만, let과 다른 특징중 하나는 const로 선언한 변수는 반드시 선언과 동시에 초기화해야한다는 것이다. 또 재할당이 불가능하다. const는 let과 같이 블록레벨스코프를 가진다. const(상수)는 일반적으로 이름을 대문자로 선언하도록 한다. ex> const TAX_RATE = 0.25

ES6이상 변수 사용팁

  • var키워드 사용하지 않는다.
  • 재할당이 필요한 경우에 한정해 let을 사용한다. 변수의 스코프는 최대한 좁게
  • 최대한 const를 사용하자.(안전성)

프로퍼티 어트리뷰트

프로퍼티는 데이터 프로퍼티와 접근자 프로퍼티로 구분할 수 있다.

  • 데이터 프로퍼티 어트리뷰트 : value-값, writable-읽기,쓰기권한, enumerable-열거가능(for,.keys), configurable-재정의
  • 접근자 프로퍼티 어트리뷰트 : get-값 호출, set-값 저장, enumerable, configurable

이러한 프로퍼티 어트리뷰트를 직접 제어할 수 있다. 객체(Object)는 세 가지의 변경방지 기능이 있다.

  • Object.preventExtensions(instance)
  • Object.seal(instance)
  • Object.freeze(instance)

아래로 갈 수록 제한의 범위가 늘어난다.

profile
자바집사의 거북이 수련법

0개의 댓글