이번 정리 목차는 16 ~ 18장이다.
16장 프로퍼티 어트리뷰트
내부 슬롯과 내부 메서드
- 이중대괄호[[]]로 감싼 이름들이 내부 슬롯과 내부 메서드
- 엔진에서 실제로 동작하지만 개발자가 직접 접근 X
- 간접적 접근 수단 제공하기는 함
- 모든 객체는 [[Prototype]]이라는 내부 슬롯 갖는다. __proto__ 통해 간접 접근 가능
프로퍼티 어트리뷰트와 프로퍼티 디스크립터 객체
- 엔진은 프로퍼티를 생성할 때 상태를 나타내는 프로퍼티 어트리뷰트를 기본값으로 자동 정의
- 프로퍼티 상태: 프로퍼티 값, 값 갱신 가능 여부, 열거 가능 여부, 재 정의 가능 여부의미
- 어트리뷰트 종류: value, Writable, Enumerable, Configurable
- Object.getOwnPropertyDescriptor 메서드 사용하여 간접 확인 가능
- 이 메서드는 프로퍼티 어트리뷰트 정보를 제공하는 프로퍼티 디스크립터 객체 반환
데이터 프로퍼티와 접근자 프로퍼티
- 프로퍼티는 데이터 프로퍼티와 접근자 프로퍼티로 구분할 수 있다.
- 데이터 프로퍼티: 키와 값으로 구성된 일반적인 프로퍼티
- 엔진이 프로퍼티 생성할 때 기본값으로 자동 정의
- value의 값은 프로퍼티 값으로 초기화, Writable, Enumerable, Configurable은 true 초기화
- [어트리뷰트 종류]
- Value: 프로퍼티 키를 통해 값에 접근하면 반환되는 값
- Writable: 값의 변경 가능 여부, 불리언 값 갖는다.
- Enumerable: 열거 가능 여부, 불리언 값을 갖는다.
- Configurable: 재정의 가능 여부, 불리언 값 갖는다.
- 접근자 프로퍼티: 자체적으로는 값을 갖지 않고 다른 데이터 프로퍼티의 값을 읽거나 저장할 때 호출되는 접근자 함수로 구성된 프로퍼티
- [어트리뷰트 종류]
- Get: 접근자 프로퍼티를 통해 데이터 프로퍼티의 값을 읽을 때 호출되는 접근자 함수
- Set: 접근자 프로퍼티를 통해 데이터 프로퍼티의 값을 저장할 때 호출되는 접근자 함수
- Enumerable: 열거 가능 여부, 불리언 값 갖는다.
- Configurable: 재정의 가능 여부, 불리언 값 갖는다.
- 접근자 함수는 getter/setter함수라고도 함. 모두 정의하거나 하나만 할 수 있다.
- 프로토타입: 어떤 객체의 상위(부모)객체의 역할을 하는 객체, 하위(자식)객체에게 자신의 프로퍼티와 메서드를 상속
- 프로토타입 체인: 프로토타입이 단방향 링크드 리스트 형태로 연결되어 있는 상속 구조
- 접근자 프로퍼티와 데이터 프로퍼티 구별방법: Object.getOwnPropertyDescriptor 메서드 사용
프로퍼티 정의
- 새로운 프로퍼티를 추가하면서 프로퍼티 어트리뷰트를 명시적 정의하거나 기존 프로퍼티의 프로퍼티 어트리뷰트를 재정의하는 것 의미
- Object.defineProperty메서드 사용, 인수로 객체, 프로퍼티 키, 프로퍼티 디스크립터 객체 전달
- value, get, set은 기본값이 undefined, writable, enumerable, configurable은 false
객체 변경 방지
- 객체 변경 방지 3가지 메서드 있음
- 객체 확장 금지: 프로퍼티 추가 금지, Object.preventExtensions메서드, Object.isExtensible메서드로 확장 가능한 객체인지 확인 가능
- 객체 밀봉: 프로퍼티 추가 및 삭제와 프로퍼티 어트리뷰트 재정의 금지, 읽기와 쓰기만 가능, Object.seal메서드, Object.isSealed로 확인 가능
- 객체 동결: 읽기만 가능, Object.freeze, Object.isFrozen로 확인 가능
불변 객체
- 상기 메서드들은 얕은 변경 방지로 중첩 객체는 영향 주지 못함
- 중첩 객체까지 동결하려면 재귀적으로 Object.freeze메서드 호출해야 함
17장 생성자 함수에 의한 객체 생성
Object 생성자 함수
- new 연산자와 Object 생성자 함수를 호출하면 빈 객체 생성하여 반환
- 빈 객체 생성 이후 프로퍼티 또는 메서드 추가하여 객체 완성
- 생성자 함수란 new 연산자와 함께 호출하여 객체를 생성하는 함수를 말한다
- 이에 의해 생성된 객체를 인스턴스라 함.
- Object 이외에도 String, Number, Boolean등 빌트인 생성자 함수 제공
객체 리터럴에 의한 객체 생성 방식 문제점
- 객체 리터럴 생성 방식은 직관적이고 간편하지만 하나의 객체만 생성
- 동일한 프로퍼티를 갖는 객체를 여러 개 생성하려면 매번 생성해야 함으로 비효율적
생성자 함수에 의한 객체 생성 방식 장점
- 프로퍼티 구조가 동일한 객체 여러 개를 간편하게 생성 가능
- this는 객체 자신의 프로퍼티나 메서드 참조하기 위한 자기 참조 변수
- this가 가리키는 값이 this 바인딩이며 함수 호출 방식에 따라 동적으로 결정
- 일반 함수 호출: this는 전역 객체를 바인딩
- 메서드 호출: this는 메서드를 호출한 객체(마침표 앞 객체)를 바인딩
- 생성자 함수 호출: this는 생성자 함수가(미래에) 생성할 인스턴스를 바인딩
- 생성자 함수는 객체(인스턴스)를 생성하는 함수
- new 연산자와 함께 호출하면 해당 함수는 생성자 함수로 동작한다.
- new 연산자와 함께 호출하지 않으면 일반 함수로 동작
생성자 함수의 인스턴스 생성 과정
- 생성자 함수 역할은 프로퍼티 구조가 동일한 인스턴스를 생성하기 위한 템플릿으로 동작하여 인스턴스를 생성하고 초기화 하는 것
- 생성자 함수는 new 연산자와 함께 생성자 함수 호출하면 엔진이 암묵적으로 인스턴스를 생성하고 초기화한 후 반환
[인스턴스 생성과 this 바인딩]
- 암묵적으로 빈 객체가 생성, 이 빈 객체가 생성자 함수가 생성한 인스턴스
- 인스턴스는 this에 바인딩 됨
- 생성자 함수 내부의 this가 생성자 함수가 생성할 인스턴스를 가리키는 이유가 바로 이것
- 런타임 이전에 실행
- 바인딩: 식별자와 값을 연결하는 과정 의미, this바인딩은 this와 this가 가리킬 객체를 바인딩하는 것, 변수 선언은 식별자(변수이름)와 확보된 메모리 공간의 주소를 바인딩하는 것
[인스턴스 초기화]
- 런타임 시 this에 바인딩되어 있는 인스턴스 초기화
- 프로퍼티나 메서드를 추가하는 작업
- 개발자가 기술함.
[인스턴스 반환]
- 모든 처리가 끝나면 완성된 인스턴스가 바인딩된 this가 암묵적 반환
- 만약 this가 아닌 다른 객체를 명시적 반환하면 명시한 객체 반환
- 원시 값을 반환하면 원시 값 반환 무시되고 암묵적 this 반환
- 명시적으로 this가 아닌 다른 값 반환하는 것은 생성자 함수의 기본 동작을 훼손함으로 반드시 return문 생략
내부 메서드 [[Call]] 과 [[Construct]]
- 함수 선언문 또는 함수 표현식으로 정의한 함수는 일반함수 호출 뿐만 아니라 생성자 함수로서 호출 가능
- 함수는 객체이지만 일반 객체와 다르게 호출이 가능하고 일반 객체가 가지고 있는 내부 슬롯과 내부 메서드는 물론 함수 객체만을 위한 내부 슬롯과 내부 메서드를 추가로 가짐
- 일반 함수로 호출되면 내부 메서드 Call이 호출되고 생성자 함수로 호출되면 Construct가 호출
- call을 갖는 함수 객체는 callable, Construct를 갖는 함수 객체는 constructor, Construct갖지 않는 함수 객체는 non-constructon라 함
- callable은 호출할 수 있는 객체, 즉 함수
- constructor는 생성자 함수로서 호출할 수 있는 함수
- non-constructor는 객체를 생성자 함수로서 호출할 수 없는 함수
- 함수 객체는 반드시 callable이어야 하지만 constructor일 수도 있고 non-constructor일 수도 있음
- 즉 모든 함수 객체는 호출할 수 있지만 모든 함수 객체를 생성자 함수로서 호출할 수 있는 것은 아님
constructor와 non-constructor구분
- 함수 정의 방식에 따라 구분
- constructor: 함수 선언문, 함수 표현식, 클래스(클래스도 함수)
- non-constructor: 화살표 함수, ES6 메서드 축약 표현
new 연산자
- new 연산자를 함께 사용하여 호출하면 생성자 함수 동작
- new 연산자 없이 생성자 함수를 호출하면 일반 함수로 호출
- 생성자 함수는 파스칼 케이스로 네이밍 하여 구별하도록 노력
new.target
- new 연산자 없이 생성자 함수가 호출 되는 것을 방지 하기 위해 파스칼 컨벤션을 사용하더라도 실수가 언제나 가능, ES6에서 이를 회피하기 위해 new.target지원
- new연산자와 함께 생성자 함수로서 호출되었는지 확인하는 것
- new.target 문법 사용 할 수 없으면 스코프 세이프 생성자 패턴 사용
- 대부분의 빌트인 생성자 함수는 new연산자와 함께 호출되었는지 확인한 후 적절한 값 반환함
- 하지만 String, Number, Boolean생성자 함수는 new 연산자와 함께 호출했을 때 객체를 생성하여 반환하지만 new 없이 호출하면 문자열, 숫자, 불리언 값을 반환. 이를 통해 데이터 타입을 변환하기도 함.
18장 함수와 일급 객체
일급 객체
- 무명의 리터럴로 생성 할 수 있다.(런타임에 생성 가능)
- 변수나 자료구조(배열,객체)에 저장할 수 있다.
- 함수의 매개변수에 전달할 수 있다.
- 함수의 반환값으로 사용할 수 있다.
- 함수는 위 조건을 다 만족하므로 일급 객체임
함수 객체의 프로퍼티
- 함수는 객체다. 함수도 프로퍼티를 가질 수 있다.
- 함수 프로퍼티 확인법: Object.getOwnPropertyDescriptors 메서드로 확인
- arguments, caller, length, name, prototype 프로퍼티는 모두 함수 객체의 데이터 프로퍼티
- 일반 객체에는 없는 함수 객체 고유 프로퍼티
- __proto__는 접근자 프로퍼티이며 Object.prototype 객체의 프로퍼티를 상속받은 것
- Object.prototype 객체의 프로퍼티는 모든 객체 상속받아 사용 가능
[arguments 프로퍼티]
- arguments 프로퍼티 값은 arguments 객체다.
- arguments객체는 함수 호출 시 전달된 인수들의 정보를 담고 있는 순회 가능한 유사배열 객체이며 함수 내부에서 지역 변수처럼 사용
- arguments객체는 인수를 프로퍼티 값으로 소유하고 프로퍼티 키는 인수의 순서를 나타냄
- callee프로퍼티는 호출되어 arguments 객체를 생성한 함수, 즉 함수 자신 가리킴
- length프로퍼티는 인수의 개수
- 매개 변수를 확정할 수 없는 가변 인자 함수를 구현할 때 유용
- 유사 배열 객체로 배열 메서드 사용시 에러, 간접 호출해야 함
- ES6에서는 Rest파라미터 도입
[caller 프로퍼티]
- ECMAScript 사양에 포함되지 않은 비표준 프로퍼티
- 함수 자신을 호출한 함수를 가리킴
[length 프로퍼티]
- 함수를 정의할 때 선언한 매개변수의 개수를 가리킴
- arguments 객체의 length는 인자의 개수를 가리키고 함수 객체의 length는 매개 변수의 개수를 가리킨다!!
[name 프로퍼티]
- 함수 객체의 name 프로퍼티는 함수 이름을 나타냄
- ES6에서 정식 표준 됨
- 익명 함수 표현식 경우 ES5에서는 name 프로퍼티가 빈 문자열이지만 ES6에서는 식별자를 값으로 갖는다.
[__proto__접근자 프로퍼티]
- 모든 객체는 [[Prototype]]이라는 내부 슬롯을 갖는다.
- 상속을 구현하는 프로토타입 객체를 가리킨다.
- __proto__프로퍼티는 [[Prototype]] 내부 슬롯이 가리키는 프로토타입 객체에 접근하기 위해 사용하는 접근자 프로퍼티다.
[prototype 프로퍼티]
- prototype 프로퍼티는 생성자 함수로 호출할 수 있는 함수 객체, 즉 constructor만이 소유하는 프로퍼티다.
- 일반 객체와 생성자 함수로 호출할 수 없는 non-constructor에는 prototype 프로퍼티가 없다
- prototype 프로퍼티는 함수가 객체를 생성하는 생성자 함수로 호출될 때 생성자 함수가 생성할 인스턴스의 프로토타입 객체를 가리킨다.
'JS DeepDive' 카테고리의 다른 글
모던 자바스크립트 DeepDive 공부 내용 8차 (0) | 2023.05.08 |
---|---|
모던 자바스크립트 DeepDive 공부 내용 7차 (0) | 2023.05.08 |
모던 자바스크립트 DeepDive 공부 내용 5차 (0) | 2023.05.08 |
모던 자바스크립트 DeepDive 공부 내용 4차 (0) | 2023.05.08 |
모던 자바스크립트 DeepDive 공부 내용 3차 (0) | 2023.05.08 |