객체는 객체 리터럴 이외에도 다양한 방법으로 생성할 수 있다.
이 포스팅에서는 생성자 함수를 이용해 객체를 생성하는 방식을 다루도록 하겠다.
Object 생성자 함수
const a = new Object();
위와 같이 new 연산자와 함께 Object 생성자 함수를 호출하면 빈 객체를 생성해서 반환한다.
이후 프로퍼티를 추가하거나, 메서드를 추가하는 등의 행위도 가능하다.
생성자 함수는 new 연산자와 함께 호출해 객체를 생성하는 함수이고,
이 생성자 함수에 의해 생성된 객체를 인스턴스라 칭한다.
자바스크립트는 Object 외에도
String, Number, Boolean, Function, Array, Date, RegExep, Promise 등의 빌트인 생성자 함수를 제공한다.
function Circle(radius) {
this.radius = radus;
this.getDiameter = function () {
return 2 * this.radius;
};
}
const c1 = new Circle(5);
const c2 = new Circle(10);
this
this 는 객체 자신의 프로퍼티나 메서드를 참조하기 위한 자기 참조 변수다.
일반 함수로서 호출하면 this 는 전역 객체가 되고,
메서드로서 호출하면 this 는 메서드를 호출한 객체가된다.
생성자 함수로서 호출하면 생성자 함수가 생성할 인스턴스를 가리키는 것이다.
자바와 같은 클래스 기반 객체지향 언어 생성자와는 달리 형식이 정해져있는 것이 아닌
일반 함수와 동일한 방법으로 생성자 함수를 정의하고
new 연산자와 함께 호출하면 해당 함수는 생성자 함수로 동작한다.
추가로 인스턴스 생성과 this 바인딩에 대해 알아보자.
우선 암묵적으로 빈 객체가 생성되고, 이 인스턴스는 this에 바인딩 된다.
이후 생성자 함수에 기술되어 있는 코드가 한 줄씩 실행되어 this에 바인딩 되어 있는 인스턴스를 초기화한다.
이 처리는 개발자가 기술한대로 진행된다.
생성자 함수 내부의 모든 처리가 끝나면 완성된 인스턴스가 바인딩된 this 가 암묵적으로 반환된다.
만약 this 가 아닌 다른 객체를 명시적으로 반환하면 this 반환이 아닌 return 한 객체가 반환된다.
만약 객체가 아닌 원시값을 반환하면 원시값 반환은 무시되고 this가 반환된다.
내부 메서드 [[Call]] 과 [[Construct]]
함수 선언문 또는 함수 표현식으로 정의한 함수는 일반적인 함수로서
생성자 함수로서도 호출할 수 있다. 이는 new 연산자와 함께 호출해 객체를 생성하는 걸 의미한다.
함수도 객체고 다른 일반 객체도 객체인데, 왜 일반 객체는 호출할 수 없을까?
함수 객체는 함수 객체만을 위한 [[Environment]], [[FormalParameters]] 등의 내부 메서드가 있다.
함수가 일반 함수로서 호출되면 함수 객체 내부 메서드 [[Call]] 이 호출되고
new 연산자와 함께 생성자 함수로서 호출되면 내부 메서드 [[Construct]] 가 호출된다.
함수는 callable (호출 가능) 은 반드시 가져야하지만,
constructor 일 수도 있고, non-constructor 일 수도 있다.
함수 선언문, 함수 표현식, 클래스는 constructor 로 함수 객체를 생성자 함수로서 호출가능하다.
메서드, 화살표 함수 는 non-constructor 로 함수 객체를 생성자 함수로서 호출할 수 없다.
추가로, 일반 함수와 생성자 함수에 특별한 형식적 차이는 없다.
따라서 생성자 함수는 일반적으로
첫 문자를 대문자로 기술하는 파스칼 케이스로 명명해 일반 함수와 구별할 수 있도록 해야한다.
함수 내부에서 new.target을 사용하면
new 연산자와 함께 생성자 함수로서 호출되었는지 확인할 수 있다.
function Circle(radius) {
if (!new.target) {
return new Circle(radius);
}
}
new 연산자와 함께 생성자 함수에 의해 생성된 인스턴스는
프로토타입에 의해 생성자 함수와 연결된다.
이를 통해서 new 연산자와 함께 호출되었는지 확인 가능하다.
참고로 대부분의 빌트인 생성자 함수(Object, String, Number .. etc) 는
new 연산자와 함께 호출되었는지를 확인하고 적절한 값을 반환한다.
따라서 Object, Function 생성자 함수는 new 연산자 없이도 new 연산자와 함께 호출했을 때와 동일하게 동작한다.
하지만 String, Number, Boolean 생성자 함수는 new 연산자 없이 호출하면 각각 문자열, 숫자, 불리언 값을 반환한다.
'Archive > Develop' 카테고리의 다른 글
[ 모던 자바스크립트 스터디 ] 프로토타입 (0) | 2022.09.28 |
---|---|
[ 모던 자바스크립트 스터디 ] 함수와 일급 객체 (1) | 2022.09.25 |
[ 모던 자바스크립트 스터디 ] 프로퍼티 어트리뷰트 (0) | 2022.09.22 |
[ PostgreSQL ] CASE WHEN ~ END 와 비교연산(<>) (0) | 2022.09.21 |
구조적 서브타이핑 / 잉여 속성 체크 (0) | 2022.09.21 |