<모던 자바스크립트 Deep Dive> 17~18장 생성자 함수에 의한 객체 생성, 함수와 일급 객체 요약
17. 생성자 함수에 의한 객체 생성
1) Object 생성자 함수
- new 연산자 + Object();으로 빈 객체(인스턴스) 생성
- Object 이외에도 String, Boolean, Function, Array, Date, RegExp, Promise 등 빌트인 생성자 함수 제공
2) 생성자 함수
1. 객체 리터럴에 의한 객체 생성 방식의 문제점
- 하나의 객체만 생성이 가능하여 비효율적(메서드가 동일한데 매 번 같은 객체 생성해야 함
2. 생성자 함수에 의한 객체 생성 방식의 단점
- 프로퍼티 구조가 동일한 객체를 여러개 생성 가능
- 사용자 정의 가능(new 연산자만 붙이면 됨)
*this : 자기참조변수로, 함수 호출 방식에 따라 this가 가리키는 값이 달라짐
함수 호출 방식 | this가 가리키는 값(this 바인딩) |
일반 함수로서 호출 | 전역 객체 |
메서드로서 호출 | 메서드를 호출한 객체(마침표 앞) |
생성자 함수로서 호출 | 생성자 함수가 생성할 인스턴스 |
3. 생성자 함수의 인스턴스 생성 과정
- 인스턴스 생성과 this 바인딩(빈 객체를 일단 만들고, this에 바인딩(식별자와 값을 연결)) -> 인스턴스 초기화(개발자가 기술한대로 초기값을 할당하여 초기화) -> 인스턴스 반환(암묵적으로 반환되므로 반환문 없이도 호출 가능하나, 반환문이 있으면 암묵적 반환이 무시되어 생성자 함수의 기본 동작을 훼손하므로 반환문이 있으면 생략 필요)
4. 내부 메서드 [[Call]]과 [[Construct]]
- 함수는 객체이기 때문에 프로퍼티, 메서드 소유 가능
- 함수만을 위한 내부 슬롯과 내부 메서드 가짐 ex. [[Call]], [[Construct]]
- callable ; 일반 함수로 호출 -> [[Call]] 호출됨
- constructor ; new + 생성자 함수로 호출 -> [[Construct]] 호출됨
- non-constructor; 생성자 함수로 호출할 수 없는 함수를 나타냄
- 함수 객체는 반드시 callable이면서 constructor이거나 non-constructor임
5. constructor와 non-constructor의 구분
- 자바스크립트 엔진이 함수 정의를 평가할 때 구분됨
- constructor ; 함수 선언문, 표현식, 클래스
- non-constructor; 메서드, 화살표 함수
6. new 연산자
- new와 함께 호출 시 생성자 함수로 동작함(constructor이어야 함)
- new 없이 호출 시 일반 함수로 동작함
- 생성자 함수는 첫문자를 대문자로 씀(일반 함수와 구분가능)
7. new.target
- 메타 프로퍼티를 나타냄
- IE에서는 지원되지 않으므로 스코프 세이프 생성자 패턴 사용 필요
- 생성자 함수로 호출 시 내부의 new.target은 함수 자신이며, 일반 함수로 호출 시 undefined임
- 일반 함수일때는 재귀호출을 통해 생성자 함수로 호출 가능함
function Circle(radius) {
if(!new.target) {
return new Circle(radius); // 재귀호출
}
this.radius = radius;
this.getDiameter = function () {
return 2 * this.radius;
};
}
const Circle = Circle(5);
console.log(circle.getDiameter());
18. 함수와 일급 객체
1) 일급 객체
- 일급 객체의 조건으로는 다음과 같은 것들이 있음1. 무명의 리터럴로 생성이 가능(런타임 시 생성)2. 변수나 자료구조에 저장이 가능3. 함수의 매개변수에 전달이 가능4. 함수의 반환값으로 사용이 가능
- 자바스크립트의 함수는 위의 4가지 조건을 모두 충족하므로 객체와 동일하게 사용이 가능함(함수형 프로그래밍 가능)
2) 함수 객체의 프로퍼티
1. arguments 프로퍼티
- 값은 arguments 객체
- arguments 객체는 함수 호출 시 전달될 인수들의 정보를 담고 있는 순회 가능한 유사 배열 객체이며, 함수 내부에서 지역 변수처럼 사용이 가능
- 매개변수 개수보다 전달된 인수의 개수가 많을 경우, 초과된 인수는 버려지지 않고 arguments 프로퍼티로 보관
- arguments 객체는 인수를 값으로, 키는 인수의 순서로 가지며, callee 프로퍼티는 arguments 객체를 생성한 함수 자신을, length 프로퍼티는 인수의 개수를 나타냄
- arguments 객체의 Symbol 프로퍼티는 arguments 객체를 순회 가능한 자료구조인 이터러블로 만들기 위한 프로퍼티임
2. caller 프로퍼티
- 비표준 프로퍼티이며, 사용하지 않음
3. length 프로퍼티
- 함수 정의 시 선언한 매개변수의 개수를 나타냄
- arguments 객체의 length 프로퍼티는 인자의 개수를, 함수 객체의 length 프로퍼티는 매개변수의 개수를 나타내므로 주의를 요함
4. name 프로퍼티
- 함수의 이름을 나타냄
- ES5에서는 빈 문자열을, ES6에서는 함수 객체가 가리키는 식별자를 값으로 가지므로 주의를 요함
5. __proto__ 접근자 프로퍼티
- [[Prototype]] 내부 슬롯이 가리키는 프로토타입 객체에 접근하기 위해 사용하는 접근자 프로퍼티(간접적 접근)
*hasOwnProperty 메서드 : 인수로 전달받은 프로퍼티 키가 객체 고유의 프로퍼티 키면 true, 상속이면 false를 반환
6. prototype 프로퍼티
- constructor만이 소유하는 프로퍼티
- 생성자 함수가 생성할 인스턴스의 프로토타입 객체
참고 : 도서 <모던 자바스크립트 Deep Dive>