Posts 모던 자바스크립트 #4.5 new 연산자와 생성자 함수
Post
Cancel

모던 자바스크립트 #4.5 new 연산자와 생성자 함수

모던 JavaScript 튜토리얼을 따라가면서 정리합니다.

4.5. new 연산자와 생성자 함수

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

생성자 함수(construction function)

  • 함수의 이름의 첫 글자는 대문자로 시작한다.
  • 반드시 new 연산자를 붙여 실행한다.
1
2
3
4
5
6
7
8
9
10
11
function User(name) {
  // this = {}; (빈 객체가 암시적으로 만들어짐)
  this.name = name;
  this.isAdmin = false;
  // return this; (this가 암시적으로 반환됨)
}

let user = new User("Jack");

alert(user.name); // Jack
alert(user.isAdmin); // false

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

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

let user = new User("Jack")은 아래 코드를 입력한 것과 동일하게 동작한다.

1
2
3
4
let user = {
  name = "Jack";
  isAdmin = false;
};
  • 객체 리터럴 문법으로 일일이 객체를 만드는 방법보다 훨씬 간단하고 읽기 쉽게 객체를 만들 수 있다.(new User("Ann"), new User("Alice"))

  • 생성자는 재사용할 수 있는 객체 생성 코드를 구현할 수 있는 데에 의의가 있다.

  • 모든 함수는 생성자가 될 수 있다. new를 붙여 실행하면 어떤 함수라도 위에 언급된 알고리즘이 실행된다.

  • 재사용할 필요가 없는 복잡한 객체익명 생성자 함수로 감싸주는 방식을 사용한다.

    1
    2
    3
    4
    5
    6
    
    let user = new function() {
      this.name = "John";
      this.isAdmin = false;
      // 사용자 객체를 만들기 위한 여러 코드
      // 지역변수, 복잡한 로직, 구문 등의 다양한 코드가 들어간다.
    }
    

new.target과 생성자 함수

  • new.target 프로퍼티를 사용하면 함수가 new와 함께 호출되었는지 아닌지를 알 수 있다.
  • 일반적인 방법으로 함수를 호출했다면 undefined를, new와 함께 호출한 경우에는 함수 자체를 반환한다.
1
2
3
4
5
6
7
function User() {
  alert(new.target);
}

User(); // undefined

new User(); // function User() {...}

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

1
2
3
4
5
6
7
8
9
10
function User(name) {
  if (!new.target) { // new 없이 호출해도
    return new User(name); // new를 붙여준다.
  }
  
  this.name = name;
}

let john = User("John"); // new User를 쓴 것처럼 바꿔준다.
alert(john.name); //John

new를 생략하면 코드가 정확히 무슨 일을 하는지 알기 어렵다. 그러므로 이 방법은 정말 필요한 경우에만 사용하고 남발하지 않는 것이 좋다.

생성자와 return 문

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

만약 return 문이 있다면

  • 객체를 return한다면 this 대신 객체가 반환된다.
  • 원시형을 return한다면 return문이 무시된다.

return 뒤에 객체가 오면 생성자 함수는 해당 객체를 반환해주고, 이 외의 경우는 this가 반환된다.

괄호 생략하기

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

1
2
3
let user = new User;
// 아래 코드는 위 코드와 똑같이 동작한다.
let user = new User();

생성자 내 메서드

생성자 함수를 사용하면 매개변수를 이용해 객체 내부를 자유롭게 구성할 수 있기 때문에 엄청난 유연성이 확보된다. 이때 프로퍼티뿐만 아니라 메서드를 this에 더해주는 것도 가능하다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
function User(name) {
  this.name = name;
  
  this.sayHi = function() {
    alert("My name is: " + this.name);
  };
}

let john = new User("John");

john.sayHi(); // My name is: John

/*
john = {
	name: "John";
	sayHi: function() {...}
}
*/

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

자바 스크립트는 언어 차원에서 다양한 생성자 함수를 제공한다. Date, Set 등 내장 객체는 이런 생성자 함수를 이용해 만들 수 있다.

과제

함수 두 개로 동일한 객체 만들기

1
2
3
4
5
6
7
8
9
let obj = {};

function A() {
  return obj;
}

function B() {
  return obj;
}

this 대신 객체를 반환하게 하면 된다.

계산기 만들기

1
2
3
4
5
6
7
8
9
10
11
12
13
14
function Calculator() {
  this.read = function() {
    this.a = +prompt("첫 번째 값을 입력하세요.");
    this.b = +prompt("두 번째 값을 입력하세요.");
  };
  
  this.sum = function() {
    return a + b;
  };
  
  this.mul = function() {
    return a * b;
  };
}

누산기 만들기

1
2
3
4
5
6
7
function Accumulator(startingValue) {
  this.value = startingValue;
  
  this.read = function () {
    this.value += +prompt("value", 0);
  };
}
This post is licensed under CC BY 4.0 by the author.

모던 자바스크립트 #4.4. 메서드와 this

모던 자바스크립트 #4.6. 옵셔널 체이닝 '?.'

Loading comments from Disqus ...