Object
생성자 함수new Object()
로 빈 객체를 생성하여 반환하며, 빈 객체에 프로퍼티 또는 메서드를 추가하여 객체를 완성할 수 있음
-> 객체 리터럴을 사용하는 방식이 더 간편하기 때문에 잘 사용하지 않음
생성자 함수(constructor) :
new
연산자와 함께 호출하여 객체를 생성하는 함수로, 이 때 생성된 객체를 인스턴스라고 부른다.
동일한 프로퍼티를 갖는 객체를 여러 개 생성해야 하는 경우 객체 리터럴 방식의 경우 매번 같은 프로퍼티를 기술해야 하기 때문에 비효율적임
-> 생성자 함수를 통해 마치 템플릿처럼 프로퍼티 구조가 동일한 객체 여러 개를 간편하게 생성할 수 있음
new
연산자와 함께 함수 호출 -> 생성자 함수로 동작function Circle(radius) {
// 1. 암묵적으로 빈 객체가 생성되고 this에 바인딩됨
console.log(this); // Circle {}
// 2. this에 바인딩된 인스턴스를 초기화함
this.radius = radius;
this.getDiameter = function () {
return 2 * this.radius;
};
// 3. 완성된 인스턴스가 바인딩된 this를 암묵적으로 반환함
}
// 0. new 연산자와 함께 함수 호출 => 생성자 함수로 동작
const circle = new Circle(1);
this
바인딩암묵적으로 빈 객체가 생성되며, 이 빈 객체가 바로 생성자 함수가 생성한 인스턴스다. 그리고 이 인스턴스는 this
에 바인딩된다. 생성자 함수 내부의 this
가 생성자 함수가 생성할 인스턴스를 가리키는 이유가 바로 이것 때문이다.
생성자 함수에 기술된 코드가 한 줄씩 실행되며 this
에 바인딩되어 있는 인스턴스를 초기화한다.
생성자 함수 내부의 모든 처리가 끝나면 완성된 인스턴스가 바인딩된 this
가 암묵적으로 반환됨
-> 만약 다른 객체가 반환되는 경우 this
대신 반환문에 명시된 해당 객체로 대체됨
-> 원시 값이 반환되는 경우 무시되고 암묵적으로 this
가 반환됨
생성자 함수 내부의 반환문은 생성자 함수의 기본 동작을 훼손하기 때문에 반드시 생략해야 한다.
[[Call]]
, [[Construct]]
함수는 객체로, 일반 객체가 가지고 있는 내부 슬롯과 메서드뿐만 아니라 함수로서 동작하기 위한 [[Environment]]
, [[FormalParameter]]
등의 내부 슬롯과 [[Call]]
, [[Construct]]
등의 내부 메서드도 추가적으로 가지고 있다.
이 때 함수가 일반 함수로서 호출되면 내부 메서드 [[Call]]
이 호출되고, new
연산자와 함께 생성자 함수로서 호출되면 내부 메서드 [[Construct]]
가 호출된다.
호출할 수 없는 객체는 함수가 아니므로, 함수는 반드시 callable
해야 하지만, 모든 함수가 반드시 constructor
이지는 않다.
constructor
로 동작할 수 있는 경우: 함수 선언문, 함수 표현식, 클래스 non-constructor
: 화살표 함수, 메서드(ES6 축약표현)new
연산자new
연산자와 함께 호출하는 함수는 반드시 constructor
이어야 한다.new
연산자 없이 생성자 함수를 호출하면 일반 함수로 호출된다. 이 때 일반 함수로 호출된 생성자 함수 내부의 this
는 전역 객체 window
를 가리킨다.function Circle(radius) {
this.radius = radius;
this.getDiameter = function () {
return 2 * this.radius;
};
}
// 일반 함수로 호출
const circle = Circle(5);
console.log(circle); // undefined
console.log(radius); // 5 (window.radius)
console.log(getDiameter()); // 10 (window.getDiameter())
일반 함수와 생성자 함수에 특별한 형식적 차이는 존재하지 않기 때문에 생성자 함수의 경우 첫 문자를 대문자로 기술하는 파스칼 케이스로 명명하여 일반 함수와 구별하는 것이 일반적이다.
new.target
new
연산자와 함께 호출하면 함수 내부의 new.target
은 함수 자신을 가리킴new.target
은 undefined
new.target
을 통해 생성자 함수를 일반 함수로 호출했는지 확인하여 그렇지 않은 경우 new
연산자와 함께 생성자 함수로 재귀 호출할 수 있다.
대부분의 빌트인 함수는
new
연산자와 함께 호출되었는지를 확인한 후 적절한 값을 반환함
Object
,Function
,Array
,RegExp
:new
연산자 없이 호출해도new
연산자와 함께 호출했을 때와 동일하게 동작String
,Number
,Boolean
:new
연산자 없이 호출 시 문자열, 숫자, 불리언 값을 반환Date
:new
연산자 없이 호출 시 현재 날짜 및 시간을 나타내는 문자열을 반환Promise
:new
연산자 없이 호출 시new Promise()
의syntactic sugar
로서 동작