const person = new Object();
//프로퍼티 추가
person.name = 'Hong';
person.sayHello = function () {
console.log("Hi! My name is " + this.name);
}
console.log(person); //{name : "Hong", sayHello : f}
동일한 프로퍼티 구조를 가지고 있는 객체를 여러개 생성할 때 생성자 함수는 유용하다. 마치 템플릿처럼 사용할 수 있다.
만약 new 연산자와 함께 호출하지 않는다면 일반 함수로 동작한다.
new 연산자와 함께 생성자 함수를 호출하면 자바스크립트 엔진은 암묵적으로 빈 객체를 생성(아직 완성 X), this에 바인딩 한다.
function Circle (radius) {
// 암묵적으로 인스턴스가 생성되고 this 에 바인딩된다.
console.log(this); // Circle{}
// this 에 바인딩되어 있는 인스턴스를 초기화한다.
this.radius = radius;
this.getDiameter = function () {
return 2 * this.radius;
};
// 이 내부의 처리가 모두 끝나면, 완성된 인스턴스가 바인딩된 this가 암묵적으로 반환된다.
// 만약 this가 아닌 다른 객체를 명시적으로 return 문을 활용하여 반환하면 return 문에 명시된 객체가 반환된다.
// 하지만 반환 값이 원시 값이라면 무시되고, this를 반환한다.
// 따라서 생성자 함수 내부에서 return문을 생략해야 한다.
}
함수 선언문, 표현식으로 정의한 함수는 생성자 함수로서 호출할 수 있다. 생성자 함수로서 호출한다는 것은 new 연산자와 함께 호출하여 객체를 생성한다는 것을 의미한다.
일반 객체와 달리 함수는 호출 할 수 있기 때문에 [[Environment]], [[FormalParameters]] 등의 내부 슬롯과 [[Call]], [[Construct]] 같은 내부 메서드를 추가로 가지고 있다.
모든 함수 객체는 내부 메서드 [[Call]]을 갖고 있으므로 호출할 수 있으며 이런 함수 객체를 callable 이라 한다.
[[Construct]] 내부 메서드를 갖는 함수 객체를 constructor, 그러지 않은 함수를 non-constructor이라 부른다. 생성자 함수로 호출 가능 유무로 나뉜다.
모든 함수 객체는 호출할 수 있지만, 모든 함수 객체를 생성자 함수로서 호출할 수 있는 것은 아니다.
자바스크립트 엔진은 함수 객체를 생성할 때 함수 저으이 방식에 따라 함수를 constructor 와 non-constructor 로 구분한다.
constructor : 함수 선언문, 함수 표현식, 클래스
non - constructor : 매서드 , 화살표 함수
일반 함수와 생성자 함수에 형식적 차이는 없다. new 연산자와 함께 함수를 호출하면 해당 함수는 생성자 함수로 동작한다.
// 생성자 함수가로서 정의하지 않은 일반 함수
function add (x,y){
return x + y;
}
// 생성자 함수로서 정의하지 않은 일반 함수를 new 연산자와 함께 호출
let inst = new add();
// 함수가 객체를 반환하지 않았으므로 반환문이 무시된다. 빈 객체 생성.
console.log(inst); //{}
// 객체를 반환하는 일반함수
function createUser(name, role) {
return {name,role};
}
let = new createUser("Lee","admin");
// 함수가 생성한 객체를 반환
console.log(inst); // {name : "Lee", role : "admin"}
function Circle(radius){
// 이 함수가 new 연산자와 함께 호출되지 않았다면 new.target은 undefined 이다.
if(!new.target){
// new 연산자와 함께 생성자 함수를 재귀 호출하여 생성된 인스턴스를 반환한다.
return new Circle(radius);
}
this.radius = radius;
this.getDiameter = function () {
return 2 * this.radius;
};
}
// new 연산자 없이 생성자 함수를 호출하여도 new.target을 통해 생성자 함수로서 호출된다.
const circle = Circle(5);
console.log(circle.getDiameter());