JavaScript 객체 - new 연산자와 생성자 함수

Leejunyoung·2022년 7월 13일
0

JavaScript

목록 보기
27/49

오늘은 모던 자바스크립트 튜토리얼 객체의 new 연산자와 생성자 함수에 대해 공부하겠습니다.

객체 리터럴 {...}을 사용하면 객체를 쉽게 만들 수 있다. 그런데 개발을 하다 보면 유사한 객체를 여러 개 만들어야 할 때가 생기곤 한다. 복수의 사용자, 메뉴 내 다양한 아이템을 객체로 표현하려고 하는 경우가 대부분이다.

'new' 연산자와 생성자 함수를 사용하면 유사한 객체 여러 개를 쉽게 만들 수 있다.

생성자 함수

생성자 함수(constructor function)와 일반 함수에 기술적인 차이는 없다. 다만 생성자 함수는 아래 두 관례를 따른다.
  1. 함수 이름의 첫 글자는 대문자로 시작한다.
  2. 반드지 'new' 연산자를 붙여 실행한다.

new User(...)를 써서 함수를 실행하면 아래와 같은 알고리즘이 동작한다.

  1. 빈 객체를 만들어 this에 할당한다.
  2. 함수 본문을 실행한다. this에 새로운 프로퍼티를 추가해 this를 수정한다.
  3. this를 반환한다.

예시를 이용해 new User(...)가 실행되면 무슨 일이 일어나는지 살펴보자.

이제 let user = User("보라")는 아래 코드를 입력한 것과 동일하게 동작한다.

new User("보라") 이외에도 new User("호진"), new User("지민") 등을 이용하면 손쉽게 사용자 객체를 만들 수 있다. 객체 리터럴 문법으로 일일이 객체를 만드는 방법보다 훨씬 간단하고 읽기 쉽게 객체를 만들 수 있게 된다.

생성자의 의의는 바로 여기에 있다. 재사용할 수 있는 객체 생성 코드를 구현하는 것이다.

모든 함수는 생성자 함수가 될 수 있다는 점을 잊지 말자. new를 붙여 실행한다면 어떤 함수라도 위에 언급된 알고리즘이 실행된다. 이름의 '첫 글자가 대문자'인 함수는 new를 붙여 실행해야 한다는 점도 잊지 말자. 공동의 약속이다.


TMI - new function() {...}

재사용할 필요가 없는 복잡한 객체를 만들어야 한다고 해보자. 많은 양의 코드가 필요할 것이다. 이럴 땐 아래와 같이 코드를 익명 생성자 함수로 감싸주는 방식을 사용할 수 있다.


new.target과 생성자 함수

new.target 프로퍼티를 사용하면 함수가 new와 함께 호출되었는지 아닌지를 알 수 있다.

일반적인 방법으로 함수를 호출했다면 new.target은 undefined를 반환한다. 반면 new와 함께 호출한 경우엔 new.target은 함수 자체를 반환해준다.

함수 본문에서 new.target을 사용하면 해당 함수가 new와 함께 호출되었는지(in constructor mode)아닌지(in regular mode)를 확인할 수 있다.

이를 활용해 일반적인 방법으로 함수를 호출해도 new를 붙여 호출한 것과 같이 동작하도록 만들어 보자.

라이브러리를 분석하다 보면 위와 같은 방식이 쓰인 걸 발견할 때가 있을 것이다. 이런 방식을 사용하면 new를 붙여 함수를 호출하든 아니든 코드가 동일하게 동작하기 때문에, 좀 더 유연하게 코드를 작성할 수 있다.

그런데 이 방법을 믿고 객체를 만드는 경우에도 new를 생략하면 코드가 정확히 무슨 일을 하는지 알기 어렵다. new가 붙어있으면 새로운 객체를 만든다는 걸 누구나 알 수 있기 때문에 new를 생략해서 객체를 만드는 것은 정말 필요한 경우에만 사용하시고 남발하지 않아야한다.

생성자와 return문

생성자 함수엔 보통 return 문이 없다. 반환해야 할 것들은 모두 this에 저장되고, this는 자동으로 반환되기 때문에 반환문을 명시적으로 써 줄 필요가 없다.

그런데 만약 return문이 있다면 어떤 일이 벌어질까 아래와 같은 규칙이 적용된다.

  • 객체를 return 한다면 this 대신 객체가 반환된다.
  • 원시형을 return 한다면 return 문이 무시된다.
  • return 뒤에 객체가 오면 생성자 함수는 해당 객체를 반환해주고, 이 외의 경우는 this가 반환된다.
    아래 예시에선 첫 번째 규칙이 적용돼 return은 this를 무시하고 객체를 반환한다.

    아무것도 return 하지 않는 예시를 살펴보자. 원시형을 반환하는 경우와 마찬가지로 두 번째 규칙이 적용된다.

    return 문이 있는 생성자 함수는 거의 없다.


    TMI - 괄호 생략하기

    인수가 없는 생성자 함수는 괄호를 생략해 호출할 수 있다.


    생성자 내 메서드

    생성자 함수를 사용하면 매개변수를 이용해 객체 내부를 자유롭게 구성할 수 있다. 엄청난 유연성이 확보된다.

    지금까지 this에 프로퍼티를 더해주는 예시만 살펴봤는데, 메서드를 더해주는 것도 가능하다.

    아래 예시에서 new User(name)는 프로퍼티 name과 메서드 sayHi를 가진 객체를 만들어준다.

    class 문법을 사용하면 생성자 함수를 사용하는 것과 마찬가지로 복잡한 객체를 만들 수 있다.

    profile
    안녕하세요

    0개의 댓글