object 생성자 함수
new 연산자와 함께 Object 생성자 함수를 호출하면 빈 객체를 생성하며 반환한다.
// 빈 객체 생성
const student = new Object();
//프로퍼티 추가
student.name = '유관순';
student.age = 16;
console.log(student); // { name: '유관순', age: 16 }
생성자 함수에 의한 객체 생성
객체 리터럴을 이용한 객체 생성 방식은 직관적이고 간편하지만, 단 하나의 객체만 생성하므로
동일 프로퍼티를 갖는 객체를 여러 개 생성해야 하는 경우 매번 같은 프로퍼티를 기술하므로 비효율적이다.
const student = {
name : '유관순',
age : 16,
getInfor () {
reurn `${this.name}(은)는 ${this.age}세 입니다.`;
}
};
const student2 = {
name : '홍길동',
age : 20,
getInfor () {
reurn `${this.name}(은)는 ${this.age}세 입니다.`;
}
};
const student3 = {
name : '선덕여왕',
age : 30,
getInfor () {
reurn `${this.name}(은)는 ${this.age}세 입니다.`;
}
};
- 객체를 생성하기 위한 템플릿처럼 생성자 함수를 사용하여 프로퍼티 구조가 동일한 객체 여러 개를 생성할 수 있다.
- 빈 객체 생성 이후 프로퍼티 또는 메서드를 추가하여 객체를 완성할 수 있다.
function Student(name, age) {
// 생성자 함수 내부의 this는 생성자 함수가 생성할 인스턴스를 가리킨다.
this.name = name;
this.age = age;
this.getInfor = function () {
return `${this.name}(은)는 ${this.age}세 입니다.`;
}
}
// 인스턴스의 생성
const student4 = new Student('장보고', 35);
const student5 = new Student('신사임당', 40);
console.log(student4); //Student { name: '장보고', age: 35, getInfor: [Function (anonymous)] }
console.log(student5); //Student { name: '신사임당', age: 40, getInfor: [Function (anonymous)] }
인스턴스 생성 과정
function Student(name, age) {
1. 암묵적으로 인스턴스가 생성되고 this에 바인딩되는 과정이 런타임 이전에 실행된다.
console.log(this); // this = Student {} => student 타입의 빈 객체
2. this에 바인딩 되어 있는 인스턴스를 초기화 한다.
this.name = name;
this.age = age;
this.getInfor = function () {
return `${this.name}(은)는 ${this.age}세 입니다.`;
}
3. 완성된 인스턴스가 바인딩 된 this가 암묵적으로 반환된다.
// Student {} 출력
만약 명시적으로 객체를 반환하면 암묵적인 this 반환이 무시된다.
return {}; // Student {} 가 아니라 {}가 반환됨
하지만 명시적으로 원시값을 반환하면 this가 반환된다.
return 1; // Student {} 반환
=> 생성자 내부에서 return은 생략하는 것이 기본이다.
}
const student = new Student('홍길동', 20);
console.log(student);
// 위의 각 경우의 출력값과 함께
//Student { name: '홍길동', age: 20, getInfor: [Function (anonymous)] }
일반 함수와의 차이점
일반 함수와 생성자 함수의 형식적인 차이는 없다.(첫 문자를 대문자로 기술하여 구별하고자 노력한다.)
단, new 연산자와 함께 호출될 때 생성자 함수로 동작하며 만약 new 연산자와 함께 호출되지 않으면 일반 함수로 동작한다.
function Student(name, age) {
console.log(this); //전역 객체
this.name = name;
this.age = age;
this.getInfor = function () {
return `${this.name}(은)는 ${this.age}세 입니다.`;
}
}
일반 함수로 호출된 Student는 반환문이 없으므로 undefined를 반환한다.
const student = Student('강감찬', 35);
console.log(student); //undefined
일반 함수로 호출된 Student내의 this는 전역 객체를 가리킨다. 전역에서 쓸 수 있는 여러가지 기능이 담겨있다.
console.log(age); //35
console.log(name); //강감찬
console.log(getInfor()); //강감찬(은)는 35세 입니다.
new.target
- 생성자 함수가 new 연산자 없이 호출되는 것을 방지하기 위해 ES6에서는 new.target을 지원한다.
- new 연산자와 함께 생성자 함수로서 호출되면 함수 내부의 new.target은 함수 자신을 가리킨다.
- new 연산자 없이 일반 함수로 호출된 함수 내부의 new.target은 undefined이다.
function Dog(name, age) {
if(!new.target) {
return new Dog(name, age);
}
this.name = name;
this.age = age;
}
=> new 연산자와 함께 호출되지 않은 경우 undefined이므로 new 연산자와 함께 생성자 함수를 재귀 호출하여 생성된 인스턴스를 반환한다.
그 후엔 new 연산자 없이 호출해도 new.target을 통해 생성자 함수로서 호출 된다.
const dog = Dog('뽀삐', 3);
console.log(dog);
//Dog { name: '뽀삐', age: 3 }
대부분의 빌트인 생성자 함수(Object, String, Number, Boolean, Date, ...)는 new 연산자와 함께 호출되었는지 확인 후 적절한 값을 반환한다.
String, Number, Boolean의 경우 new 연산자 없이 호출하면 객체 값이 아닌 문자열 숫자, 불리언 값(원시 값)을 반환한다. 이를 데이터 타입 변환에 활용하는 것이다.
'LECTURE > JavaScript' 카테고리의 다른 글
strict mode - 엄격 모드 (0) | 2023.02.09 |
---|---|
프로토타입 - 상속, 생성자 함수 프로토타입, Object 프로토타입, 모던 메소드 (0) | 2023.02.09 |
scope - 전역과 지역 스코프, 함수 레벨 스코프, var/let/const (0) | 2023.02.07 |
Function - 화살표 함수, 즉시 실행 함수, 재귀 함수, 중첩 함수, 콜백 함수, 순수 함수와 비순수 함수 (0) | 2023.02.07 |
Function - 함수의 표현식, 함수 호이스팅, 매개변수와 인수, 반환문, 일급 객체 (0) | 2023.02.07 |