JS/[web] 코어 JS 튜토리얼

[코어 JS] 4.5 - 객체: new 연산자와 생성자 함수

web_seul 2021. 10. 11. 11:04
반응형

4.4 new 연산자와 생성자 함수

복수의 사용자, 메뉴 내 다양한 아이템 객체 표현 등 유사한 객체를 여러개 만들어야 하는 경우 'new' 연산자

 

- 생성자 함수(constructor function)

1. 함수 이름의 첫 글자는 대문자로 시작

2. 반드시 'new' 연산자를 붙여 실행

function User(name) {
  this.name = name;
  this.isAdmin = false;
}

let user = new User("보라");

alert(user.name); // 보라
alert(user.isAdmin); // false

new User()를 사용했을 때 알고리즘

1. 빈 객체를 만들어 this에 할당

2. 함수 본문 실행, this에 새로운 프로퍼티 추가, this 수정

3. this 반환

function User(name) {
  // this = {};  (빈 객체가 암시적으로 만들어짐)

  // 새로운 프로퍼티를 this에 추가함
  this.name = name;
  this.isAdmin = false;

  // return this;  (this가 암시적으로 반환됨)
}

//let user = new User("보라")의 동작
let user = {
  name: "보라",
  isAdmin: false
};

new User('보라'), new User('호진').. 등 new 연산자를 활용하여 간단히 객체 생성 가능

-> 생성자의 의의 : 재사용할 수 있는 객체 생성 코드 구현

! 모든 함수는 new를 붙여 실행하면 생성자 함수가 될 수 있음 new + '첫글자가 대문자'인 함수

 

+ new function(){...}

재사용이 불필요한 객체 생성시, 익명 생성자 함수로 감싸주는 방식

let user = new function() {
  this.name = "John";
  this.isAdmin = false;

  // 사용자 객체를 만들기 위한 여러 코드.
  // 지역 변수, 복잡한 로직, 구문 등의
  // 다양한 코드가 여기에 들어갑니다.
};

-> 익명 함수이기 때문에 저장되지 않음, 처음부터 일회성 호출 목적으로 생성되어 재사용이 불가능, 익명생성자 함수 이용시 재사용은 막고 코드 캡슐화 가능

 

- new.target과 생성자 함수(참고용, 사용빈도낮음)

new.target프로퍼티를 사용하여 함수가 new와 함께 호출 여부 확인 가능

일반 호출에서 new.target은 undefined 반환, new와 호출할 때는 new.target 함수 자체 반환

function User() {
  alert(new.target);
}

// 'new' 없이 호출함
User(); // undefined

// 'new'를 붙여 호출함
new User(); // function User { ... }

 

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

//일반 호출시 생성자 호출 기능

function User(name) {
  if (!new.target) { // new 없이 호출해도
    return new User(name); // new를 붙여줍니다.
  }

  this.name = name;
}

let bora = User("보라"); // 'new User'를 쓴 것처럼 바꿔줍니다.
alert(bora.name); // 보라

질문??? function User에서도 무조건 대문자?

! 해당방법으로 new를 생략해서도 객체생성이 가능하지만 코드의 정확한 역할 파악이 어려우므로 권장x

 

- 생성자와 return문

생성자 함수는 반환할 것들이 this에 저장되고 자동으로 반환되기 때문에 반환문인 return을 명시적으로 쓸 필요x

but, return문이 있다면

1. 객체를 return한다면 this대신 객체가 반환됨

2. 원시형을 return한다면 return문이 무시됨

//1. return은 this를 무시하고 객체를 반환

function BigUser() {
  this.name = "원숭이";
  return { name: "고릴라" };  // <-- this가 아닌 새로운 객체를 반환함
}

alert( new BigUser().name );  // 고릴라
//2. 아무것도 return하지않는 경우, return문이 무시됨

function SmallUser() {
  this.name = "원숭이";
  return; // <-- this를 반환함
}

alert( new SmallUser().name );  // 원숭이

+ return문이 있는 생성자 함수는 거의 없음

 

!괄호 생략하기 _ 인수가 없는 생성자 함수는 괄호를 생략해 호출가능 / 권장x

let user = new User; // <-- 괄호가 없음
// 아래 코드는 위 코드와 똑같이 동작합니다.
let user = new User();

 

- 생성자 내 메서드

생성자 함수를 사용하면 매개변수를 이용해 객체 내부를 자유롭게 구성 가능, 유연성 확보

this에 프로퍼티뿐 아니라 메서드를 더해주는 것도 가능

//new User(name)은 프로퍼티 name과 메서드 sayHi를 가진 객체를 만듬

function User(name) {
  this.name = name;

  this.sayHi = function() {
    alert( "제 이름은 " + this.name + "입니다." );
  };
}

let bora = new User("이보라");

bora.sayHi(); // 내 이름은 이보라입니다.

/*
bora = {
   name: "이보라",
   sayHi: function() { ... }
}
*/

+ class문법을 사용해서 복잡한 객체 생성 가능

 

요약

- 생성자 함수(=생성자)는 일반 함수 이지만 일반 함수와 구분을 위해 첫글자를 대문자로 사용

- 생성자 함수는 반드시 new연산자와 함께 호출, new와 함께 호출하면 내부에서 this가 암시적으로 만들어지고 마지막에 this가 반환

생성자 함수는 유사한 객체를 여러개 만들때 유용

생성자 함수를 이용해 날짜를 나타낼때 Date, 집합을 나타낼때 Set 등 내장 객체를 만들 수 있음

 

반응형