우주선

모던 자바스크립트 Deep Dive ― (3) 본문

JavaScript

모던 자바스크립트 Deep Dive ― (3)

선주우 2022. 9. 21. 23:10

 

모던 자바스크립트 Deep Dive ― (3)

 

모던자바스크립트 Deep Dive, 이웅모 지음

 

13장 스코프 

 

13.1 스코프란

스코프란 식별자가 유효한 범위를 말한다. 모든 식별자는 자신이 선언된 위치에 의해 다른 코드가 식별자 자신을 참조할 수 있는 유효 범위가 있다. 예를 들어 함수의 매개변수는 함수 몸체 내부에서만 참조할 수 있다. 이는 매개변수를 참조할 수 있는 유효범위인 스코프가 함수 몸체 내부로 한정되기 때문이다. 스코프는 자바스크립트 엔진이 식별자를 검색할 때 사용하는 규칙이기도 하다. 

스코프 내에서 식별자는 유일해야 하지만 다른 스코프에는 같은 이름의 식별자를 사용할 수 있다. 

 

코드의 문맥과 랙시컬 환경

렉시컬 환경 : 코드가 어디서 실행되며 주변에 어떤 코드가 있는지

코드의 문맥 (context) : 랙시컬 환경으로 이루어짐 

 

13.2 스코프의 종류

변수는 자신이 선언된 위치에 의해 스코프가 결정된다. 전역에서 선언된 변수는 전역 스코프를 갖는 전역 변수이고,

지역에서 선언한 변수는 지역 스코프를 갖는 지역 변수다.

지역 스코프는 자신의 지역 스코프와 하위 지역 스코프에서 유효하다.

 

13.3 스코프 체인

스코프 체인이란 스코프가 계층적으로 연결된 것이다. 

변수를 참조할 때 자바스크립트 엔진은 스코프 체인을 통해 변수를 참조하는 코드의 스코프에서 시작하여 상위 스코프 방향으로 이동하여 선언된 변수를 검색한다. 이를 통해 상위 스코프에서 선언한 변수를 하위 스코프에서도 참조할 수 있다. 즉 상위 스코프에서 유효한 변수는 하위에서 참조할 수 있지만, 하위 스코프에서 유효한 변수는 상위 스코프에서 참조할 수 없다.

 

13.4 함수 레벨 스코프 

var 키워드로 선언된 변수는 오로지 함수의 코드 블록(함수 몸체)만을 지역 스코프로 인정한다. 이러한 특성을 함수 레벨 스코프라고 한다. 

let, const 키워드는 블록 레벨 스코프를 지원한다. (15장에 계속) 

 

13.5 렉시컬 스코프

동적 스코프 : 함수를 어디서 호출했는지에 따라 함수의 상위 스코프를 결정한다.

정적 스코프 ( 렉시컬 스코프 ): 함수를 어디서 정의했는지에 따라 함수의 상위 스코프를 결정한다. 함수 정의가 평가되는 시점에 상위 코프가 정적으로 결정된다. 함수가 호출된 위치는 상위 스코프 결정에 영향을 주지 않는다.

자바스크립트는 렉시컬 스코프를 따른다.  

 

 

14장 전역 변수의 문제점 

 

14.1 변수의 생명 주기

변수의 생명 주기는 변수가 생성되어 소멸의 단계까지 이르는 것을 말한다. 엄밀히 말해서 메모리 공간이 확보된 시점부터 메모리 공간이 해제되어 가용 메모리 폼에 반환되는 시점까지다. 

변수는 자신이 등록된 스코프가 소멸(메모리해제)될때까지 유효하다. 

 

전역 변수의 경우 런타임 이전 단계에서 자바스크립트 엔진에 의해 미리 변수 선언이 되기 때문에 전역 객체(ex.브라우저 환경의window)의 생명 주기와 같다. 

그러나 지역 변수의 생명 주기는 함수의 생명 주기와 일치한다.

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

애플리케이션 전체가 아닌 스코프 기준이라는 것이다.

 

14.2 전역 변수의 문제점

- 암묵적 결합 : 모든 코드가 전역 변수를 참조하고 변경할 수 있다. 

- 긴 생명 주기 : 메모리 리소스 사용량이 크다. 

- 스코프 체인 상에서 종점에 존재 : 자바스크립트 엔진이 변수를 탐색하는 데 시간이 걸린다.

 

14.3 전역 변수의 사용을 억제하는 방법

- 즉시 실행 함수를 사용한다.

- 네임스페이스 객체를 생성하여 전역 변수처럼 사용한다.

- 모듈 패턴 : 캡슐화를 통해 정보를 은닉한다. 

 

 

15장 let, const 키워드와 블록 레벨 스코프 

 

15.1 var 키워드로 선언한 변수의 문제점

- 변수 중복 선언을 허용한다.

- 함수 레벨 스코프 : 함수 코드 블록만을 지역 스코프로 인정하여 코드 블록 내에서 선언해도 전역 변수가 된다.

- 변수 호이스팅 : 변수 선언과 초기화가 동시에 일어난다. 

 

15.2 let 키워드

- 변수 중복 선언을 금지한다. 

- 블록 레벨 스코프 : 모든 코드 블록을 지역 스코프로 인정한다. 

- 변수 호이스팅 : 변수의 선언 단계와 초기화 단계가 분리되어 진행되기 떄문에 let으로 선언한 변수는 스코프의 시작 지점부터 초기화를 시작하여, 초기화 시작 지점까지 변수를 참조할 수 없는 일시적 사각지대 구간을 만든다.

 

15.3 const 키워드

- 선언과 동시에 초기화된다. 

- 블록 레벨 스코프를 가진다.

- 재할당이 금지된다. 

- 일반적으로 상수의 이름은 대문자와 언더스코어(_)를 사용한다. 예를 들어 'TAX_RATE'

- 호이스팅이 발생되지 않는 것처럼 동작한다.

- 하지만 그걸 아는가? const 키워드로 선언된 변수의 원시 값은 변경 불가능하지만, 객체를 할당한 경우 값을 변경할 수 있다. 즉 재할당을 금지할 뿐 불변을 의미하진 않는다. 객체 변경 시 변수에 할당된 참조 값이 동일하기 떄문이다. 

 

 

16장 프로퍼티 어트리뷰트 

 

16.1 내부 슬롯과 내부 메서드 

자바스크립트 엔진의 구현 알고리즘을 설명하기 위해 ECMAScript에서 사용하는 의사 프로퍼티와 의사 메서드이다. 

자바스크립틍 엔진의 내부 로직이므로 원칙적으로는 접근하거나 호출할 수 없고 일부만 가능하다.

예를 들어 모든 객체는 [[Prototype]] 이라는 내부 슬롯을 갖는다. 직접 접근을 할 수 없는 것이 원칙이지만 __proto__ 등을 통해 간접 접근이 가능하다.

 

16.2 프로퍼티 어트리뷰트와 프로퍼티 디스크립터 객체

자바스크립트 엔진은 프로퍼티를 생성할때 프로퍼티의 상태를 나타내는 프로퍼티 어트리뷰트를 기본값으로 자동정의한다.

프로퍼티의 상태란 프로퍼티의 값value, 값의 갱신 가능 여부writable, 열거 가능 여부enumerable, 재정의 가능 여부configurable 를 말한다.

프로퍼티 어트리뷰트는 자바스크립트 엔진이 관리하는 내부 상태 값인 내부 슬롯이다. 간접적으로 확인 가능하다.

 

16.3 데이터 프로퍼티와 접근자 프로퍼티

- 데이터 프로퍼티

키와 값으로 이루어진 일반적인 프로퍼티

프로퍼티 어트리뷰트로 [[Value]] [[Writable]] [[Enumerable]] [[Configurable]]을 갖는다.

- 접근자 프로퍼티

자체적으로는 값을 갖지 않고 다른 데이터 프로퍼티의 값을 읽거나 저장할 떄 호출되는 접근자 함수로 구성된 프로퍼티

프로퍼티 어트리뷰트로 [[Get]] [[Set]] [[Enumerable]] [[Configurable]]을 갖는다.

 

16.4 프로퍼티 정의 

새로운 프로퍼티를 추가하면서 프로퍼티 어트리뷰트를 명시적으로 정의하거나 기존 프로퍼티의 프로퍼티 어트리뷰트를 재정의하는 것이다.

Object.defineProperty(person,'firstName',{
	value:'space',
    writable:true,
    enumerable:true,
    configurable:true
})

 

16.5 객체 변경 방지

자바스크립트는 객체의 변경을 방지하는 메서드를 제공한다.

- 객체 확장 금지 : Object.preventExtensions ( 프로퍼티 추가 불가능 ) 

- 객체 밀봉 : Object.seal ( 읽기 쓰기만 가능 )

- 객체 동결 : Object.freeze ( 읽기만 가능 )

Comments