deep js - 5일차

2024. 5. 21. 23:44JS

14 전역 변수의 문제

 

14.1 변수의 생명 주기 

14.1.1 지역 변수의 생명 주기

지역변수의 생명주기는 함수의 생명 주기와 일치

 

14.1.2 전역 변수의 생명 주기

 var 키워드로 선언한 전역 변수의 생명 주기는 전역 객체의 생명 주기와 일치

 

14.2 전역 변수의 문제점

암묵적 결합

-변수의 유효 범위가 크면 클수록 코드의 가독성은 나빠지고 의도치 않게 상태가 변굉될 수 있는 위험성도 높아짐

 

긴 생명 주기

전역 변수는 생명 주기가 긺

 

스코프 체인 상에서 종점에 존재

전역 변수의 검색 속도가 가장 느림

 

네임스페이스 오염

자바스크립트의 가장 큰 문제점 중 하나 파일이 분리되어 있어도 하나의 전역 스코프를 공유한다는 것

 

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

14.3.1 즉시 실행 함수

모든 코드를 즉시 실행 함수로 감싸면 모든 변수는 즉시 실행 함수의 지역변수가 됨

 

14.3.2 넴스페이스 객체

전역에 네임스페이스 역할을 담당할 객체를 생성하고 전역 변수처럼 사용하고 싶은 변수를 프로퍼티를 추가하는 방법

옛날 방식임 비추천

 

14.3.3 모듈 패턴

24장 클로저에서

 

14.3.4 ES6 모듈

ES6 모듈은 파일 자체의 독자적인 모듈 스코프를 제공 

script 테그에 type="module" 어트리뷰트를 추가하면 로드된 자바스크립트 파일은 모듈로서 동작

모듈 파일의 확장자는 mjs를 권장

 

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

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

15.1.1 변수 중복 선언 허용

var x =1;

var y=1;

 

//var  키워드로 선언된 변수는 같은 스코프 내에서 중복 선언을 허용

//초기화문이 있는 변수 선언문은 자바스크립트 엔진에 의해 var 키워드가 없는 것처럼 동작

var x = 100;

 

//초기화 문이 없는 변수 선언문은 무시된다.

var y ;

 

console.log(x); // 100

console.log(y); // 1

 

15.1.2 함수 레벨 스코프

var 키워드로 선언한 변수는 오로지 함수의 코드 블록만을 지역 스코프로 인정

for. if 문은 지역스코프 안됨

 

15.1.3 변수 호이스팅

변수 파트에서 var 런타임 이전에 undefined로 초기화 되는 그내용임

 

15.2 let 키워드

15.2.1 변수 중복 선언 금지

var 는 중복선언이 가능하다고 했음

let, const 키워드로 =중복 선언된 변수는 같은 스코프 내에서 중복선언을 허용하지 않음

 

15.2.2 블록레벨 스코프

var는 함수만 지역스코프

let 키워드로 선언한 변수는 모든 코드 블록(함수, if 문, for 문, while문, try/catch 문 등)을 지역 스코프로 인정하는 블록 레벨 스코프를 다름

 

15.2.3 변수 호이스팅

런타임 이전 선언 -> tdz -> 초기화 이전 -> let foo = undefinde (초기화단계) -> foo = 1 

 

15.2.4 전역 객체와 let

var 키워드로 선언한 전역 변수와 전역 함수, 그리고 선언하지 않은 변수에 값을 할당한 암묵적 전역은 전역 객체 window의 프로퍼티가 됨

// 전역 변수

var x = 1;

//암묵적 전역

y = 2; 

//전역 함수

function foo ( ) { }

 

15.3 const 키워드

15.3.1 선언과 초기화

const 키워드로 선언한 변수는 반드시 선언과 동시에 초기화 해야 함

const foo  = 1 ;

const foo ;  // SyntaxError : Missing initialzier in const declaration

 

const 키워드로 선언한 변수는 let 키워드로 선언한 변수와 마찬가지로 블록 레벨 스코프를 가지며, 변수 호이스팅이 발생함

{

console.log(foo); // referenceError: Cannot access 'foo' before initialization

const foo = 1;

console.log(foo) ; //1

}

 

15.3.2 재할당 금지

const 키워드로 선언한 변수 재할당 금지

 

15.3.3 상수

상수는 재할당이 금지된 변수를 말함

 

15.3.4  const 키워드와 객체

const 키워드로 선언된 변수에 객체를 할당할 경우 값을 변경 할 수 있음

const person = {

name : lee 

};

 

//객체는 변경 가능한 값. 따라서 재할당 없이 변경 가능

person.name = 'kim' ;

 

console.log(person); // {name ;  'kim'}

 

15.4 var vs. let vs. const

var, let ,const 키워드 사용 권장사항

es6 사용시 var 키워드 사용하지 않음

재할당이 필요한 경우에 한정 let 키워드를 사용 , 이때 변수의 스코프는 최대한 좁게 만듦

변경이 발생하지 않고 읽기 전용으로 사용하는 (재할당이 필요없는 상수) 원시 값과 객체에는 const 키워드를 사용

->어지간하면  const 써라.

 

 

16. 프로퍼티 어트리뷰트

16.1 내부 슬롯과 내부 메서드

ECMAScript 사양에 등장하는 이중 대괄호 ( [[ ... ]] )로 감싼 이름들이 내부 슬릇과 내부 메서드임

개발자가 직접 접근할 수 있도록 외부에 공개된 객체의 프로퍼티는 아님

모든 객체는 [[Prototype]]이라는 내부 슬롯을 가짐 

_ _ proto_ _를 통해 간접적으로 접근 가능 <- 이 방식 없앨 예정

 

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

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

프로퍼티의 상태란 프로퍼티의 값(value), 값의 갱신 여부(writable), 열거 가능 여부(enumerable), 재정의 가능 여부(configurable)을 말함

프로퍼티 어트리뷰트는 내부 상태 값인 내부 슬롯 [[Value]], [[Wrtiable]], [[Enumerable]], [[Configurable]]

object.getOwnPropertyDescriptor 메서드를 사용하여 간접적으로 확인 할 수 있음

 

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

16.3.1 데이터 프로퍼티

프로퍼티 어트리뷰트    프로퍼티 디스크립터 객체의 프로퍼티                 설명

[[Value]]                            value                                                 프로퍼티 키를 통해 프로퍼티 값에 접근하면 반환되는 값

[[Writable]]                        writable                                             프로퍼티 값의 변경 가능 여부를 나타내며 불리언 값 가짐

[[Enumerbale]]                  enumerable                                      프로퍼티의 열거 기능 여부를 나타내며 불리언 값 가짐

[[Configurable]]                configurable                                      프로퍼티의 재정의 가능 여부를 나타내며 불리언 값 가짐

 

16.3.2 접근자 프로퍼티

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

[[Get]]                                      get

[[Set]]                                       set

[[Enumerable]]                      enumerable

[[Configurable]]                      configurable

접근자 함수는 getter/setter 함수라고도 부름

 

16.4 프로퍼티 정의

프로퍼티 디스크립터 객체의 프로퍼티               대응하는 프로퍼티 어트리뷰트            생략했을 때의 기본값

value                                                                      [[Value]]                                                   undefined

get                                                                          [[Get]]                                                      undefined

set                                                                          [[Set]]                                                       undefined

writable                                                                  [[Writable]]                                                   false

enumberable                                                          [[Enumerable]]                                            false

configurable                                                           [[Configurable]]                                            false

 

Object.defineProperty 메서드는 한번에 하나의 프로퍼티만 정의 할 수 있음

Object.defineProperties 메서드를 사용하면 여러 개의 프로퍼티를 한 번에 정의할 수 있음

 

16.5 객체 변경 방지

구분              메서드            프로퍼티추가   프로퍼티삭제   프로퍼티값읽기   프로퍼티값쓰기   프로퍼티어트리뷰트재정의

객체확장금지 object.preevenExtions x               o                        o                              o                                    o

객체 밀봉 object.seal                    x                     x                        o                              o                                    x

객체 동결 object.freeze                 x                     x                        o                              x                                    x

 

16.5.4 불변 객체

객체의 중첩 객체까지 동결하여 변경이 불가능한 읽기 전용의 붋변 객체를 구현하려면 객체를 값으로 갖는 모든 프로퍼티에 대해 재귀적으로 object.freeze 메서드를 호출해야 됨

 

17 생성자 함수에 의한 객체 생성

 

17.1 Object 생성자 함수

new 연산자와 함께 Object 생성자 함수를 호출하면 빈객체를 생성하여 반환

const person = new object ( ) ;

생성자 함수란 new연산자와 함께 호출하여 객체(인스턴스)를 생성하는 함수

생성자에 의해 생성된 객체를 인스턴스라고함

 

17.2 생성자 함수

17.2.1 객체 리터럴에 의한 객체 생성 방식의 문제점

객체 리터럴에 의한 생성 방식은 단 하나만의 객체를 생성 

- 동일한 프로퍼티를 갖는 객체를 여러 개 생성하는 경우 매번 같은 프로퍼티 기술해야 하므로 비효율

 

17.2.2 생성자 함수에 의한 객체 생성 방식의 장점

위의 비효율을 해결 

//생성자 함수 

function Circle(radius) {

//생성자 함수 내부의 this 는 생성자 함수가 생성할 인스턴스를 가리킴

this.radius = radius ;

this.getDiameter = functio ( ) {

return 2 * thid.radius ;

   };

}

 

인스턴스 생성

const circle1 = new Circle( 5); // 반지름 5인 circle 객체 생성

const circle2  = new Circle(10); // 반지름 10인 circle 객체 생성

 

17.2.3 생성자 함수의 인스턴스 생성과정

 

17.2.4 내부 메서드 [[Call]]과 [[Construct]]

일반 객체는 호출할 수 없지만 함수는 호출할 수 있다.

함수가 일반 함수로서 호출되면 함수 객체의 내부 메서드 [[Call]]이 호출되고,

new 연산자와 함께 생성자 함수로서 호출되면 [[Construct]]가 호출

 

17.2.5 constructor와 non-constructor의 구분

 

17.2.6 new연산자

 

17.2.7 new.target

new연산자와 함께 생성자 함수로서 호출되면 함수 내부의 new.target은 함수 자신을 가리킴

new연산자 없이 일반 함수로서 호출된 함수 내부의 new.target은 undefined

 

 

'JS' 카테고리의 다른 글

deep js - 7일차  (0) 2024.05.23
deep js - 6 일차  (0) 2024.05.23
deep js - 4일차  (0) 2024.05.20
deep js - 3일차  (0) 2024.05.19
deep js - 2일차  (0) 2024.05.18