Kimsora✨
article thumbnail
320x100
반응형

Object 생성자 함수

새로운 객체를 생성할 때 사용된다

 

빈 객체 생성

var obj = new Object();

 

객체 리터럴과 유사한 형태로 객체 생성

var obj = new Object({ name: 'John', age: 25 });

 

다른 객체를 복사하여 새로운 객체생성

var oldObj = { name: 'John', age: 25 };
var newObj = new Object(oldObj);

⇒객체 리터럴을 사용하여 객체를 생성하는 것이 더 간편하고 직관적

 

 

 

 

생성자함수

자바스크립트에서 객체를 생성하기 위해 사용되는 함수 생성자 함수는 일반 함수와 동일한 방식으로 정의되지만, 객체를 생성할 때 new 연산자를 사용하여 호출

  1. 새로운 빈 객체를 생성
  2. 이 빈 객체의 프로토타입을 생성자 함수의 프로토타입 객체로 설정
  3. 생성자 함수 내부의 this를 빈 객체로 설정
  4. 생성자 함수 내부의 코드를 실행하여 이 빈 객체에 프로퍼티와 메소드를 추가
  5. 빈 객체를 반환
function Person(name, age) {
  this.name = name;
  this.age = age;
}

var john = new Person('John', 25);

 

 

 

객체 리터럴에 의한 객체생성 방식의 문제점

  • 객체 내부에서 사용되는 메서드나 속성이 중복될 가능성이 높다 ⇒유지보수가 어려워 질수 있다
const person1 = {
  name: 'John',
  age: 30,
  getFullName: function() {
    return this.name;
  }
};

const person2 = {
  name: 'Jane',
  age: 25,
  getFullName: function() {
    return this.name;
  }
};
  • 다른 객체를 상속받을수 없다(단하나의 객체만생성) ⇒동일한 프로퍼티를 갖는 객체를 생성할 때 매번 같은 프로퍼티를 기술해야한다

  • 객체 리터럴 내부에서 선언된 변수는 전역 변수로 취급되어 객체 리터럴 외부에서도 접근할 수 있다 ⇒의도하지 않는 변수 충돌을 유발해 디버깅이 어려워진다

 

 

 

생성자 함수에 의한 객체 생성 방식의 장점

  • 인스턴스를 생성하기 위한 템플릿처럼 생성자 함수를 사용하여 프로퍼티 구조가 동일한 객체 여러개를 간편하게 생성 할수 있다

  • 생성자 함수에서 사용하는 기능을 활용 가능함
    ⇒생성자 함수를 사용하면 this를 활용하여 객체의 프로퍼티를 초기화할 수 있다. 또한, 생성자 함수에서 제공하는 다양한 기능들을 활용하여 객체를 더욱 다양하게 구현할 수 있다.
  • new 연산자와 함께 호출하면 해당 함수는 생성자 함수로 동작 ⇒만약 new 연산자와 함께 생성자 함수를 호출하지 않으면 생성자 함수가 아니라 일반함수로 동작

 

생성자 함수의 인스턴스 생성과정

인스턴스를 생성하는 것과 생성된 인스턴스를 초기화(인스턴스 프로퍼티 추가및 초기값 할당) 하는것

  • 인스턴스 생성과 this 바인딩
    ⇒생성자 함수 내부에서 this는 새로운 객체를 참조한다

 

  • 인스턴스 초기화

생성자 함수에서 인스턴스를 생성한후 생성된 인스터스에 대해 프로퍼티 값을 할당하거나 메소드를 호출하여 초기값을 설정하는 작업 ⇒this에 바인딩되어 있는 인스턴스를 초기화 ,인스턴스를 초기하지 않으면 생성된 인스턴스는 undefined나 null 등의 값으로 초기화

 

  • 인스턴스 반환

**return**문을 사용하여 명시적으로 객체를 반환하는 경우와 그렇지 않은 경우가 있다

-명시적으로 객체를 반환하는 경우: **return**문에 객체를 명시적으로 반환 ⇒반환되는 객체는 생성자 함수가 생성한 인스터스가 아니라면 생성자 함수가 생성한 인스턴스 무시

function Person(name) {
  this.name = name;
  return {age: 20};
}

const person = new Person('Tom');
console.log(person); // {age: 20}

-명시적으로 객체를 반환하지 않는 경우: **return**문이 없거나, **return**문에 아무것도 명시되어 있지 않다⇒생성자 함수가 생성한 인스턴스가 반환

function Person(name) {
  this.name = name;
}

const person = new Person('Tom');
console.log(person); // Person {name: 'Tom'}

-**return**문에 원시값을 명시하는 경우: 원시값이 명시 되었더라도 반환되는 값은 생성자 함수가 생성한 인스턴스가 반환

function Person(name) {
  this.name = name;
  return 'Hello, world!';
}

const person = new Person('Tom');
console.log(person); // Person {name: 'Tom'}

-**return**문에 객체가 아닌 다른 객체지향 개념인 **this**를 명시하는 경우: 생성자 함수가 생성한 인스턴스가 반환

function Person(name) {
  this.name = name;
  return this;
}

const person = new Person('Tom');
console.log(person); // Person {name: 'Tom'}

 

 

내부 메서드 [call]과 [construct]

함수와 클래스의 동작 방식을 결정하는 중요한 메서드이다

  • [call] 메서드는 함수 객체에 대해 호출 연산자 ()가 사용될 때 실행되는 내부 메서드 ⇒함수가 실행될 때 인자를 전달받고 결과값을 반환
function myFunction(a, b) {
  return a + b;
}

myFunction(1, 2); // 3
  • [construct] 메서드는 클래스 객체에 대해 new 연산자가 사용될 때 실행되는 내부 메서드
    ⇒새로운 객체를 생성하고 초기화한 후 반환 
  • class MyClass { constructor(a, b) { this.a = a; this.b = b; } } const myObject = new MyClass(1, 2); console.log(myObject); // {a: 1, b: 2}

 

 

constructor 와 non-constructor의 구분

객체 생성 방식에 따라 구분된다

  • constructor는 new 연산자와 함께 호출 가능한 함수를 의미 ⇒일반적인 함수 선언문과 함수 표현식, 그리고 ES6에서 도입된 class 문법
// 함수 선언문
function Person(name, age) {
  this.name = name;
  this.age = age;
}

const person1 = new Person('John', 30);
console.log(person1); // Person { name: 'John', age: 30 }

// 함수 표현식
const Animal = function(name, species) {
  this.name = name;
  this.species = species;
}

const animal1 = new Animal('Dog', 'Mammal');
console.log(animal1); // Animal { name: 'Dog', species: 'Mammal' }

// 클래스
class Car {
  constructor(make, model) {
    this.make = make;
    this.model = model;
  }
}

const car1 = new Car('Toyota', 'Corolla');
console.log(car1); // Car { make: 'Toyota', model: 'Corolla' }
  • non-constructor는 new 연산자와 함께 호출할 수 없는 함수를 의미 ⇒this를 사용하지 않거나, 객체를 반환하지 않는다 ,화살표 함수가 있다
const sum = (a, b) => a + b;
const result = sum(1, 2);
console.log(result); // 3

const hello = () => console.log('Hello');
hello(); // Hello

화살표 함수는 this를 바인딩하지 않으며, 객체를 생성하지 않는다,new 연산자와 함께 사용할 수 없다

 

 

new 연산자

constructor 함수를 호출하고, constructor 함수가 반환하는 객체를 생성하여 반환 ⇒call이 호출되는게 아니다

new 연산자 없이 생성자 함수를 호출하면 일반함수로 호출 ⇒constructor가 호출되는게 아니라 call 이 호출된다

 

 

new.tartget

  • constructor 함수 내부에서 다른 constructor 함수를 호출할 때, new.target을 사용하여 호출된 함수가 constructor 함수인지 확인할 수 있다
    ⇒호출된 함수가 constructor 함수인지 확인하고, 올바른 클래스의 constructor 함수를 호출
class Animal {
  constructor() {
    console.log(new.target); // Animal
  }
}

class Dog extends Animal {
  constructor() {
    super();
    console.log(new.target); // Dog
  }
}

const animal = new Animal(); // Animal
const dog = new Dog(); // Animal, Dog
  • new 연산자를 사용하지 않고 constructor 함수를 호출하면, new.target은 undefined가 된다
    ⇒new 연산자를 사용하여 호출되었는지 확인할 수 있다
    function Person(name, age) {
      if (!new.target) {
        throw new Error('Person must be called with new');
      }
      this.name = name;
      this.age = age;
    }
    
    const person1 = new Person('John', 30);
    console.log(person1); // Person { name: 'John', age: 30 }
    
    // const person2 = Person('John', 30); 
    // Error: Person must be called with new
    
728x90
반응형
profile

Kimsora✨

@sorarar

포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!

검색 태그

WH