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 연산자 없이 호출하면 객체 값이 아닌 문자열 숫자, 불리언 값(원시 값)을 반환한다. 이를 데이터 타입 변환에 활용하는 것이다.

 

+ Recent posts