ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 생성자와 new
    개발 2020. 4. 12. 21:55

     

     

    생성자( cunstructor )는 객체를 만드는 일을 하는 함수입니다. 이 함수는 재사용 가능한 로직의 묶음이 아니라 객체를 만드는 창조자라고 볼 수 있습니다. 함수를 호출할 때 new를 붙이면 새로운 객체를 만든 후에 이를 리턴합니다. 객체를 만드는 주체는 함수입니다. 

     

    이 전에 작성한 객체지향 프로그래밍 컨텐츠에서 유저의 정보를 담고있는 객체를 해당 유저가 새로 생길 때마다 새로운 객체를 만들어줘야 했고, 그 객체안에는 유저의 정보를 담고있는데, 중복되는 정보들이 있었던 것을 보았습니다. 그 중복을 줄이기 위해서 다음과 같은 코드로 작성할 수 있겠습니다.

     

     

    생성자와 new를 사용하기 전 써주었던 코드는 아래와 같고

    let person1 = {
      name: 'hyojin',
      age: 25,
      country: 'seoul',
      introduce: function(){
        return 'my name is ' + this.name;
      }
    }
    
    let person2 = {
      name: 'jack',
      age: 30,
      country: 'busan',
      introduce: function(){
        return 'my name is ' + this.name;
      }
    }

     

    이 코드를 생성자와 new를 사용하여 아래와 같이 작성할 수 있습니다.

     

    function Person(name, age, country){
      this.name = name;
      this.age = age;
      this.country = country;
      this.introduce = function(){
        return 'my name is ' + this.name;
      }
    }
    
    let person1 = new Person( 'hyojin', 25, 'seoul' );
    console.log(person1.introduce());  // my name is hyojin
    
    let person2 = new Person( 'jack', 30, 'busan' );
    console.log(person2.introduce());  // my name is jack

     

    Person은 생성자 함수 입니다.

     

    new 키워드를 사용하여 만들어진 빈 객체가 어떠한 프로퍼티들을 가져야 되고 어떠한 메소드를 가져야 하는지를 생성자 함수 안에 정의하는 것을 통해서 그 객체가 가지고 있는 정보, 할 일들을 세팅 해주고 있는데 이런 것들을 초기화라고 합니다.

    ( 생성자 함수는 일반함수와 구분하기 위해서 첫글자를 대문자로 표시합니다. )

     

    생성자와 new를 사용하기 전 코드에서는 유저가 생길 때 마다 중복되는 코드를 계속해서 써주어야 했지만 생성자함수 Person을 사용하고 난 후에는 중복을 제거하면서 코드의 재사용성이 매우 높아졌습니다.

     

    생성자함수를 선언하면서 초기화를 해주었고 이 생성자 함수를 person1과 person2 각각의 유저에 new Person(); 으로 new 키워드를 사용하여 생성자 함수를 호출하여 새로운 객체를 반환하도록 작성해주었습니다.

     

     

    그렇다면 new Person() 을 호출하여 생성자함수를 생성하는 과정에서 어떠한 일이 일어나고 있는지 다음 그림을 통해서 분석해보겠습니다.

     

    앞서 설명한 것처럼 new라는 키워드를 사용하여 생성자 함수 Person을 호출하였고 이 함수의 전달 인자로 각각의 값들을 넣어주었습니다.

    이 값은 생성자 함수 Person의 매개변수로 들어가서 this.name, this.age ... 등등의 property에 할당이 됩니다.

    (이 컨텐츠에서는 this를 다루진 않습니다. this는 생성자 함수를 호출할 때 this바인딩 편에서 다루고 있습니다.)

     

     

    만약, new 키워드를 사용하지 않고 Person을 호출하면 어떻게 될까요? new를 사용했을 때와 사용하지 않았을 때의 차이점을 console에 찍어보고 비교해보겠습니다.

     

     

    person1에 new키워드를 사용하지 않고 person만 호출했을 때는 생성자 함수 Person에서 아무 값도 리턴하고 있지 않기 때문에 undefined 를 반환합니다.

     

    person2에 new키워드를 사용하여 person을 호출했을 때는 보이는 것처럼 객체를 반환하는 것을 볼 수 있습니다.

    (위에 생성 과정을 분석한 그림에서 new 키워드는 빈 객체를 생성한다고 했습니다)

    객체를 반환하기 전, Person함수의 전달인자로 넘겨준 인자들이 각각의 프로퍼티에 잘 들어가 있는 것도 확인할 수 있습니다.

     

    만약, person1이라는 유저에서 만큼은 introduce 메소드에서 다른 값을 리턴하게 설정해두고 싶다면 다음과 같은 방법도 있습니다.

    person1.introduce = function(){
      return 'I am ' + this.age + ' years old';
    }
    person1.introduce();   // "I am 25 years old"

     

    person1.introduce()를 실행하면 자바스크립트는 먼저 person1이라는 객체에 introduce라는 메소드가 정의된 적이 있는지를 먼저 확인한 후, 자신이 해당 메서드를 가지고 있다면 그 것을 실행하고 끝납니다. 자기자신이 가지고 있는 값이 더 우선순위가 된다는 말입니다.

    만약, 자기자신이 가지고 있지 않다면 자기자신을 생성한 생성자함수의 내부에서 찾게 됩니다.

     

     

     

    생성자 함수 안에 메서드를 정의할 때 생기는 문제점

     

    new Person()을 호출할 때마다 Person이 실행되며 새로운 객체를 반환한다고 했는데 이 생성자 함수 안에 정의한 introduce라는 메소드는 new Person으로 새로운 객체가 생성될 때마다 새로 만들어지고 있습니다.

     

    즉, 생성자를 만든 목적 중 하나인 중복을 제거하자라는 의도가 새로운 객체가 생성될 때마다 introduce 메서드가 중복해서 매번 새로 만들어지고 있으니 메모리가 그만큼 낭비된다는 문제점이 발생합니다.

    왜냐하면 위의 코드에서는 2개의 객체만을 만들고 있지만 만약 몇백개의 객체를 새로 만들어야 한다면 객체를 생성할 때마다 introduce와 같은 메서드 함수를 생성하는 시간이 들테니까요.

     

    그렇다면 이 문제를 해결하고자 하는 개발자라면 이 메서드를 어딘가에 단 한번만 정의해두고 새로 생성된 여러개의 객체들이 이 메서드를 공통적으로 사용하며 공유할 수 있다면 문제점이 해결되지 않을까? 라는 생각을 하게됩니다.

     

    이 방법은 다음 컨텐츠인 prototype과 prototype Chain 이라는 컨텐츠에서 이어서 알아보도록 하겠습니다. 

     

     

    '개발' 카테고리의 다른 글

    함수의 인수 (rest와 arguments 객체)  (0) 2020.04.14
    prototype과 prototype Chain  (0) 2020.04.14
    객체지향 프로그래밍  (0) 2020.04.12
    재귀함수  (0) 2020.04.12
    클로저에 대해서  (0) 2020.04.01
Designed by Tistory.